sinic.hh revision 7811
112077Sgedare@rtems.org/* 212077Sgedare@rtems.org * Copyright (c) 2004-2005 The Regents of The University of Michigan 312077Sgedare@rtems.org * All rights reserved. 412077Sgedare@rtems.org * 512077Sgedare@rtems.org * Redistribution and use in source and binary forms, with or without 612077Sgedare@rtems.org * modification, are permitted provided that the following conditions are 712077Sgedare@rtems.org * met: redistributions of source code must retain the above copyright 812077Sgedare@rtems.org * notice, this list of conditions and the following disclaimer; 912077Sgedare@rtems.org * redistributions in binary form must reproduce the above copyright 1012077Sgedare@rtems.org * notice, this list of conditions and the following disclaimer in the 1112077Sgedare@rtems.org * documentation and/or other materials provided with the distribution; 1212077Sgedare@rtems.org * neither the name of the copyright holders nor the names of its 1312077Sgedare@rtems.org * contributors may be used to endorse or promote products derived from 1412077Sgedare@rtems.org * this software without specific prior written permission. 1512077Sgedare@rtems.org * 1612077Sgedare@rtems.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712077Sgedare@rtems.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812077Sgedare@rtems.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912077Sgedare@rtems.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012077Sgedare@rtems.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112077Sgedare@rtems.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212077Sgedare@rtems.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312077Sgedare@rtems.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412077Sgedare@rtems.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512077Sgedare@rtems.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612077Sgedare@rtems.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712077Sgedare@rtems.org * 2812077Sgedare@rtems.org * Authors: Nathan Binkert 2912077Sgedare@rtems.org */ 3012077Sgedare@rtems.org 3112077Sgedare@rtems.org#ifndef __DEV_SINIC_HH__ 3212077Sgedare@rtems.org#define __DEV_SINIC_HH__ 3312077Sgedare@rtems.org 3412077Sgedare@rtems.org#include "base/inet.hh" 3512077Sgedare@rtems.org#include "base/statistics.hh" 3612077Sgedare@rtems.org#include "dev/etherint.hh" 3712077Sgedare@rtems.org#include "dev/etherpkt.hh" 3812077Sgedare@rtems.org#include "dev/io_device.hh" 3912077Sgedare@rtems.org#include "dev/pcidev.hh" 4012077Sgedare@rtems.org#include "dev/pktfifo.hh" 4112077Sgedare@rtems.org#include "dev/sinicreg.hh" 4212077Sgedare@rtems.org#include "params/Sinic.hh" 4312077Sgedare@rtems.org#include "sim/eventq.hh" 4412077Sgedare@rtems.org 4512077Sgedare@rtems.orgnamespace Sinic { 4612077Sgedare@rtems.org 4712077Sgedare@rtems.orgclass Interface; 4812077Sgedare@rtems.orgclass Base : public PciDev 4912077Sgedare@rtems.org{ 5012077Sgedare@rtems.org protected: 5112077Sgedare@rtems.org bool rxEnable; 5212077Sgedare@rtems.org bool txEnable; 5312077Sgedare@rtems.org Tick clock; 5412077Sgedare@rtems.org inline Tick ticks(int numCycles) const { return numCycles * clock; } 5512077Sgedare@rtems.org 5612077Sgedare@rtems.org protected: 5712077Sgedare@rtems.org Tick intrDelay; 5812077Sgedare@rtems.org Tick intrTick; 5912077Sgedare@rtems.org bool cpuIntrEnable; 6012077Sgedare@rtems.org bool cpuPendingIntr; 6112077Sgedare@rtems.org void cpuIntrPost(Tick when); 6212077Sgedare@rtems.org void cpuInterrupt(); 6312077Sgedare@rtems.org void cpuIntrClear(); 6412077Sgedare@rtems.org 6512077Sgedare@rtems.org typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent; 6612077Sgedare@rtems.org friend void IntrEvent::process(); 6712077Sgedare@rtems.org IntrEvent *intrEvent; 6812077Sgedare@rtems.org Interface *interface; 6912077Sgedare@rtems.org 7012077Sgedare@rtems.org bool cpuIntrPending() const; 7112077Sgedare@rtems.org void cpuIntrAck() { cpuIntrClear(); } 7212077Sgedare@rtems.org 7312077Sgedare@rtems.org/** 7412077Sgedare@rtems.org * Serialization stuff 7512077Sgedare@rtems.org */ 7612077Sgedare@rtems.org public: 7712077Sgedare@rtems.org virtual void serialize(std::ostream &os); 7812077Sgedare@rtems.org virtual void unserialize(Checkpoint *cp, const std::string §ion); 7912077Sgedare@rtems.org 8012077Sgedare@rtems.org/** 8112077Sgedare@rtems.org * Construction/Destruction/Parameters 8212077Sgedare@rtems.org */ 8312077Sgedare@rtems.org public: 8412077Sgedare@rtems.org typedef SinicParams Params; 8512077Sgedare@rtems.org const Params *params() const { return (const Params *)_params; } 8612077Sgedare@rtems.org Base(const Params *p); 8712077Sgedare@rtems.org}; 8812077Sgedare@rtems.org 8912077Sgedare@rtems.orgclass Device : public Base 9012077Sgedare@rtems.org{ 9112077Sgedare@rtems.org protected: 9212077Sgedare@rtems.org /** Receive State Machine States */ 9312077Sgedare@rtems.org enum RxState { 9412077Sgedare@rtems.org rxIdle, 9512077Sgedare@rtems.org rxFifoBlock, 9612077Sgedare@rtems.org rxBeginCopy, 9712077Sgedare@rtems.org rxCopy, 9812077Sgedare@rtems.org rxCopyDone 9912077Sgedare@rtems.org }; 10012077Sgedare@rtems.org 10112077Sgedare@rtems.org /** Transmit State Machine states */ 10212077Sgedare@rtems.org enum TxState { 10312077Sgedare@rtems.org txIdle, 10412077Sgedare@rtems.org txFifoBlock, 10512077Sgedare@rtems.org txBeginCopy, 10612077Sgedare@rtems.org txCopy, 10712077Sgedare@rtems.org txCopyDone 10812077Sgedare@rtems.org }; 10912077Sgedare@rtems.org 11012077Sgedare@rtems.org /** device register file */ 11112077Sgedare@rtems.org struct { 11212077Sgedare@rtems.org uint32_t Config; // 0x00 11312077Sgedare@rtems.org uint32_t Command; // 0x04 11412077Sgedare@rtems.org uint32_t IntrStatus; // 0x08 11512077Sgedare@rtems.org uint32_t IntrMask; // 0x0c 11612077Sgedare@rtems.org uint32_t RxMaxCopy; // 0x10 11712077Sgedare@rtems.org uint32_t TxMaxCopy; // 0x14 11812077Sgedare@rtems.org uint32_t ZeroCopySize; // 0x18 11912077Sgedare@rtems.org uint32_t ZeroCopyMark; // 0x1c 12012077Sgedare@rtems.org uint32_t VirtualCount; // 0x20 12112077Sgedare@rtems.org uint32_t RxMaxIntr; // 0x24 12212077Sgedare@rtems.org uint32_t RxFifoSize; // 0x28 12312077Sgedare@rtems.org uint32_t TxFifoSize; // 0x2c 12412077Sgedare@rtems.org uint32_t RxFifoLow; // 0x30 12512077Sgedare@rtems.org uint32_t TxFifoLow; // 0x34 12612077Sgedare@rtems.org uint32_t RxFifoHigh; // 0x38 12712077Sgedare@rtems.org uint32_t TxFifoHigh; // 0x3c 12812077Sgedare@rtems.org uint64_t RxData; // 0x40 12912077Sgedare@rtems.org uint64_t RxDone; // 0x48 13012077Sgedare@rtems.org uint64_t RxWait; // 0x50 13112077Sgedare@rtems.org uint64_t TxData; // 0x58 13212077Sgedare@rtems.org uint64_t TxDone; // 0x60 13312077Sgedare@rtems.org uint64_t TxWait; // 0x68 13412077Sgedare@rtems.org uint64_t HwAddr; // 0x70 13512077Sgedare@rtems.org uint64_t RxStatus; // 0x78 13612077Sgedare@rtems.org } regs; 13712077Sgedare@rtems.org 13812077Sgedare@rtems.org struct VirtualReg { 13912077Sgedare@rtems.org uint64_t RxData; 14012077Sgedare@rtems.org uint64_t RxDone; 14112077Sgedare@rtems.org uint64_t TxData; 14212077Sgedare@rtems.org uint64_t TxDone; 14312077Sgedare@rtems.org 14412077Sgedare@rtems.org PacketFifo::iterator rxIndex; 14512077Sgedare@rtems.org unsigned rxPacketOffset; 14612077Sgedare@rtems.org unsigned rxPacketBytes; 14712077Sgedare@rtems.org uint64_t rxDoneData; 14812077Sgedare@rtems.org 14912077Sgedare@rtems.org Counter rxUnique; 15012077Sgedare@rtems.org Counter txUnique; 15112077Sgedare@rtems.org 15212077Sgedare@rtems.org VirtualReg() 15312077Sgedare@rtems.org : RxData(0), RxDone(0), TxData(0), TxDone(0), 15412077Sgedare@rtems.org rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) 15512077Sgedare@rtems.org { } 15612077Sgedare@rtems.org }; 15712077Sgedare@rtems.org typedef std::vector<VirtualReg> VirtualRegs; 15812077Sgedare@rtems.org typedef std::list<unsigned> VirtualList; 15912077Sgedare@rtems.org Counter rxUnique; 16012077Sgedare@rtems.org Counter txUnique; 16112077Sgedare@rtems.org VirtualRegs virtualRegs; 16212077Sgedare@rtems.org VirtualList rxList; 16312077Sgedare@rtems.org VirtualList rxBusy; 16412077Sgedare@rtems.org int rxActive; 16512077Sgedare@rtems.org VirtualList txList; 16612077Sgedare@rtems.org 16712077Sgedare@rtems.org int rxBusyCount; 16812077Sgedare@rtems.org int rxMappedCount; 16912077Sgedare@rtems.org int rxDirtyCount; 17012077Sgedare@rtems.org 17112077Sgedare@rtems.org uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } 17212077Sgedare@rtems.org uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } 17312077Sgedare@rtems.org uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } 17412077Sgedare@rtems.org 17512077Sgedare@rtems.org protected: 17612077Sgedare@rtems.org RxState rxState; 17712077Sgedare@rtems.org PacketFifo rxFifo; 17812077Sgedare@rtems.org PacketFifo::iterator rxFifoPtr; 179 bool rxEmpty; 180 bool rxLow; 181 Addr rxDmaAddr; 182 uint8_t *rxDmaData; 183 unsigned rxDmaLen; 184 185 TxState txState; 186 PacketFifo txFifo; 187 bool txFull; 188 EthPacketPtr txPacket; 189 int txPacketOffset; 190 int txPacketBytes; 191 Addr txDmaAddr; 192 uint8_t *txDmaData; 193 int txDmaLen; 194 195 protected: 196 void reset(); 197 198 void rxKick(); 199 Tick rxKickTick; 200 typedef EventWrapper<Device, &Device::rxKick> RxKickEvent; 201 friend void RxKickEvent::process(); 202 203 void txKick(); 204 Tick txKickTick; 205 typedef EventWrapper<Device, &Device::txKick> TxKickEvent; 206 friend void TxKickEvent::process(); 207 208 /** 209 * Retransmit event 210 */ 211 void transmit(); 212 void txEventTransmit() 213 { 214 transmit(); 215 if (txState == txFifoBlock) 216 txKick(); 217 } 218 typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent; 219 friend void TxEvent::process(); 220 TxEvent txEvent; 221 222 void txDump() const; 223 void rxDump() const; 224 225 /** 226 * receive address filter 227 */ 228 bool rxFilter(const EthPacketPtr &packet); 229 230/** 231 * device configuration 232 */ 233 void changeConfig(uint32_t newconfig); 234 void command(uint32_t command); 235 236/** 237 * device ethernet interface 238 */ 239 public: 240 bool recvPacket(EthPacketPtr packet); 241 void transferDone(); 242 virtual EtherInt *getEthPort(const std::string &if_name, int idx); 243 244/** 245 * DMA parameters 246 */ 247 protected: 248 void rxDmaDone(); 249 friend class EventWrapper<Device, &Device::rxDmaDone>; 250 EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent; 251 252 void txDmaDone(); 253 friend class EventWrapper<Device, &Device::txDmaDone>; 254 EventWrapper<Device, &Device::txDmaDone> txDmaEvent; 255 256 Tick dmaReadDelay; 257 Tick dmaReadFactor; 258 Tick dmaWriteDelay; 259 Tick dmaWriteFactor; 260 261/** 262 * Interrupt management 263 */ 264 protected: 265 void devIntrPost(uint32_t interrupts); 266 void devIntrClear(uint32_t interrupts = Regs::Intr_All); 267 void devIntrChangeMask(uint32_t newmask); 268 269/** 270 * Memory Interface 271 */ 272 public: 273 virtual Tick read(PacketPtr pkt); 274 virtual Tick write(PacketPtr pkt); 275 virtual void resume(); 276 277 void prepareIO(int cpu, int index); 278 void prepareRead(int cpu, int index); 279 void prepareWrite(int cpu, int index); 280 // Fault iprRead(Addr daddr, int cpu, uint64_t &result); 281 282/** 283 * Statistics 284 */ 285 private: 286 Stats::Scalar rxBytes; 287 Stats::Formula rxBandwidth; 288 Stats::Scalar rxPackets; 289 Stats::Formula rxPacketRate; 290 Stats::Scalar rxIpPackets; 291 Stats::Scalar rxTcpPackets; 292 Stats::Scalar rxUdpPackets; 293 Stats::Scalar rxIpChecksums; 294 Stats::Scalar rxTcpChecksums; 295 Stats::Scalar rxUdpChecksums; 296 297 Stats::Scalar txBytes; 298 Stats::Formula txBandwidth; 299 Stats::Formula totBandwidth; 300 Stats::Formula totPackets; 301 Stats::Formula totBytes; 302 Stats::Formula totPacketRate; 303 Stats::Scalar txPackets; 304 Stats::Formula txPacketRate; 305 Stats::Scalar txIpPackets; 306 Stats::Scalar txTcpPackets; 307 Stats::Scalar txUdpPackets; 308 Stats::Scalar txIpChecksums; 309 Stats::Scalar txTcpChecksums; 310 Stats::Scalar txUdpChecksums; 311 312 Stats::Scalar totalVnicDistance; 313 Stats::Scalar numVnicDistance; 314 Stats::Scalar maxVnicDistance; 315 Stats::Formula avgVnicDistance; 316 317 int _maxVnicDistance; 318 319 public: 320 virtual void regStats(); 321 virtual void resetStats(); 322 323/** 324 * Serialization stuff 325 */ 326 public: 327 virtual void serialize(std::ostream &os); 328 virtual void unserialize(Checkpoint *cp, const std::string §ion); 329 330 public: 331 Device(const Params *p); 332 ~Device(); 333}; 334 335/* 336 * Ethernet Interface for an Ethernet Device 337 */ 338class Interface : public EtherInt 339{ 340 private: 341 Device *dev; 342 343 public: 344 Interface(const std::string &name, Device *d) 345 : EtherInt(name), dev(d) 346 { } 347 348 virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } 349 virtual void sendDone() { dev->transferDone(); } 350}; 351 352} // namespace Sinic 353 354#endif // __DEV_SINIC_HH__ 355