sinic.hh revision 2665
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Nathan Binkert 29 */ 30 31#ifndef __DEV_SINIC_HH__ 32#define __DEV_SINIC_HH__ 33 34#include "base/inet.hh" 35#include "base/statistics.hh" 36#include "dev/etherint.hh" 37#include "dev/etherpkt.hh" 38#include "dev/io_device.hh" 39#include "dev/pcidev.hh" 40#include "dev/pktfifo.hh" 41#include "dev/sinicreg.hh" 42#include "sim/eventq.hh" 43 44namespace Sinic { 45 46class Interface; 47class Base : public PciDev 48{ 49 protected: 50 bool rxEnable; 51 bool txEnable; 52 Tick clock; 53 inline Tick cycles(int numCycles) const { return numCycles * clock; } 54 55 protected: 56 Tick intrDelay; 57 Tick intrTick; 58 bool cpuIntrEnable; 59 bool cpuPendingIntr; 60 void cpuIntrPost(Tick when); 61 void cpuInterrupt(); 62 void cpuIntrClear(); 63 64 typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent; 65 friend void IntrEvent::process(); 66 IntrEvent *intrEvent; 67 Interface *interface; 68 69 bool cpuIntrPending() const; 70 void cpuIntrAck() { cpuIntrClear(); } 71 72/** 73 * Serialization stuff 74 */ 75 public: 76 virtual void serialize(std::ostream &os); 77 virtual void unserialize(Checkpoint *cp, const std::string §ion); 78 79/** 80 * Construction/Destruction/Parameters 81 */ 82 public: 83 struct Params : public PciDev::Params 84 { 85 Tick clock; 86 Tick intr_delay; 87 }; 88 89 Base(Params *p); 90}; 91 92class Device : public Base 93{ 94 protected: 95 /** Receive State Machine States */ 96 enum RxState { 97 rxIdle, 98 rxFifoBlock, 99 rxBeginCopy, 100 rxCopy, 101 rxCopyDone 102 }; 103 104 /** Transmit State Machine states */ 105 enum TxState { 106 txIdle, 107 txFifoBlock, 108 txBeginCopy, 109 txCopy, 110 txCopyDone 111 }; 112 113 /** device register file */ 114 struct { 115 uint32_t Config; // 0x00 116 uint32_t Command; // 0x04 117 uint32_t IntrStatus; // 0x08 118 uint32_t IntrMask; // 0x0c 119 uint32_t RxMaxCopy; // 0x10 120 uint32_t TxMaxCopy; // 0x14 121 uint32_t RxMaxIntr; // 0x18 122 uint32_t VirtualCount; // 0x1c 123 uint32_t RxFifoSize; // 0x20 124 uint32_t TxFifoSize; // 0x24 125 uint32_t RxFifoMark; // 0x28 126 uint32_t TxFifoMark; // 0x2c 127 uint64_t RxData; // 0x30 128 uint64_t RxDone; // 0x38 129 uint64_t RxWait; // 0x40 130 uint64_t TxData; // 0x48 131 uint64_t TxDone; // 0x50 132 uint64_t TxWait; // 0x58 133 uint64_t HwAddr; // 0x60 134 } regs; 135 136 struct VirtualReg { 137 uint64_t RxData; 138 uint64_t RxDone; 139 uint64_t TxData; 140 uint64_t TxDone; 141 142 PacketFifo::iterator rxPacket; 143 int rxPacketOffset; 144 int rxPacketBytes; 145 uint64_t rxDoneData; 146 147 Counter rxUnique; 148 Counter txUnique; 149 150 VirtualReg() 151 : RxData(0), RxDone(0), TxData(0), TxDone(0), 152 rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) 153 { } 154 }; 155 typedef std::vector<VirtualReg> VirtualRegs; 156 typedef std::list<int> VirtualList; 157 Counter rxUnique; 158 Counter txUnique; 159 VirtualRegs virtualRegs; 160 VirtualList rxList; 161 VirtualList rxBusy; 162 int rxActive; 163 VirtualList txList; 164 165 uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } 166 uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } 167 uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } 168 169 protected: 170 RxState rxState; 171 PacketFifo rxFifo; 172 PacketFifo::iterator rxFifoPtr; 173 bool rxEmpty; 174 bool rxLow; 175 Addr rxDmaAddr; 176 uint8_t *rxDmaData; 177 int rxDmaLen; 178 179 TxState txState; 180 PacketFifo txFifo; 181 bool txFull; 182 EthPacketPtr txPacket; 183 int txPacketOffset; 184 int txPacketBytes; 185 Addr txDmaAddr; 186 uint8_t *txDmaData; 187 int txDmaLen; 188 189 protected: 190 void reset(); 191 192 void rxKick(); 193 Tick rxKickTick; 194 typedef EventWrapper<Device, &Device::rxKick> RxKickEvent; 195 friend void RxKickEvent::process(); 196 197 void txKick(); 198 Tick txKickTick; 199 typedef EventWrapper<Device, &Device::txKick> TxKickEvent; 200 friend void TxKickEvent::process(); 201 202 /** 203 * Retransmit event 204 */ 205 void transmit(); 206 void txEventTransmit() 207 { 208 transmit(); 209 if (txState == txFifoBlock) 210 txKick(); 211 } 212 typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent; 213 friend void TxEvent::process(); 214 TxEvent txEvent; 215 216 void txDump() const; 217 void rxDump() const; 218 219 /** 220 * receive address filter 221 */ 222 bool rxFilter(const EthPacketPtr &packet); 223 224/** 225 * device configuration 226 */ 227 void changeConfig(uint32_t newconfig); 228 void command(uint32_t command); 229 230/** 231 * device ethernet interface 232 */ 233 public: 234 bool recvPacket(EthPacketPtr packet); 235 void transferDone(); 236 void setInterface(Interface *i) { assert(!interface); interface = i; } 237 238/** 239 * DMA parameters 240 */ 241 protected: 242 void rxDmaDone(); 243 friend class EventWrapper<Device, &Device::rxDmaDone>; 244 EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent; 245 246 void txDmaDone(); 247 friend class EventWrapper<Device, &Device::txDmaDone>; 248 EventWrapper<Device, &Device::txDmaDone> txDmaEvent; 249 250 Tick dmaReadDelay; 251 Tick dmaReadFactor; 252 Tick dmaWriteDelay; 253 Tick dmaWriteFactor; 254 255/** 256 * Interrupt management 257 */ 258 protected: 259 void devIntrPost(uint32_t interrupts); 260 void devIntrClear(uint32_t interrupts = Regs::Intr_All); 261 void devIntrChangeMask(uint32_t newmask); 262 263/** 264 * Memory Interface 265 */ 266 public: 267 virtual Tick read(Packet *pkt); 268 virtual Tick write(Packet *pkt); 269 270 void prepareIO(int cpu, int index); 271 void prepareRead(int cpu, int index); 272 void prepareWrite(int cpu, int index); 273 // Fault iprRead(Addr daddr, int cpu, uint64_t &result); 274 275/** 276 * Statistics 277 */ 278 private: 279 Stats::Scalar<> rxBytes; 280 Stats::Formula rxBandwidth; 281 Stats::Scalar<> rxPackets; 282 Stats::Formula rxPacketRate; 283 Stats::Scalar<> rxIpPackets; 284 Stats::Scalar<> rxTcpPackets; 285 Stats::Scalar<> rxUdpPackets; 286 Stats::Scalar<> rxIpChecksums; 287 Stats::Scalar<> rxTcpChecksums; 288 Stats::Scalar<> rxUdpChecksums; 289 290 Stats::Scalar<> txBytes; 291 Stats::Formula txBandwidth; 292 Stats::Formula totBandwidth; 293 Stats::Formula totPackets; 294 Stats::Formula totBytes; 295 Stats::Formula totPacketRate; 296 Stats::Scalar<> txPackets; 297 Stats::Formula txPacketRate; 298 Stats::Scalar<> txIpPackets; 299 Stats::Scalar<> txTcpPackets; 300 Stats::Scalar<> txUdpPackets; 301 Stats::Scalar<> txIpChecksums; 302 Stats::Scalar<> txTcpChecksums; 303 Stats::Scalar<> txUdpChecksums; 304 305 public: 306 virtual void regStats(); 307 308/** 309 * Serialization stuff 310 */ 311 public: 312 virtual void serialize(std::ostream &os); 313 virtual void unserialize(Checkpoint *cp, const std::string §ion); 314 315/** 316 * Construction/Destruction/Parameters 317 */ 318 public: 319 struct Params : public Base::Params 320 { 321 Tick tx_delay; 322 Tick rx_delay; 323 bool rx_filter; 324 Net::EthAddr eaddr; 325 uint32_t rx_max_copy; 326 uint32_t tx_max_copy; 327 uint32_t rx_max_intr; 328 uint32_t rx_fifo_size; 329 uint32_t tx_fifo_size; 330 uint32_t rx_fifo_threshold; 331 uint32_t rx_fifo_low_mark; 332 uint32_t tx_fifo_high_mark; 333 uint32_t tx_fifo_threshold; 334 Tick dma_read_delay; 335 Tick dma_read_factor; 336 Tick dma_write_delay; 337 Tick dma_write_factor; 338 bool rx_thread; 339 bool tx_thread; 340 bool rss; 341 uint32_t virtual_count; 342 bool zero_copy; 343 bool delay_copy; 344 bool virtual_addr; 345 }; 346 347 protected: 348 const Params *params() const { return (const Params *)_params; } 349 350 public: 351 Device(Params *params); 352 ~Device(); 353}; 354 355/* 356 * Ethernet Interface for an Ethernet Device 357 */ 358class Interface : public EtherInt 359{ 360 private: 361 Device *dev; 362 363 public: 364 Interface(const std::string &name, Device *d) 365 : EtherInt(name), dev(d) { dev->setInterface(this); } 366 367 virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } 368 virtual void sendDone() { dev->transferDone(); } 369}; 370 371/* namespace Sinic */ } 372 373#endif // __DEV_SINIC_HH__ 374