sinic.hh revision 2282
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 29#ifndef __DEV_SINIC_HH__ 30#define __DEV_SINIC_HH__ 31 32#include "base/inet.hh" 33#include "base/statistics.hh" 34#include "dev/etherint.hh" 35#include "dev/etherpkt.hh" 36#include "dev/io_device.hh" 37#include "dev/pcidev.hh" 38#include "dev/pktfifo.hh" 39#include "dev/sinicreg.hh" 40#include "mem/bus/bus.hh" 41#include "sim/eventq.hh" 42 43namespace Sinic { 44 45class Interface; 46class Base : public PciDev 47{ 48 protected: 49 bool rxEnable; 50 bool txEnable; 51 Tick clock; 52 inline Tick cycles(int numCycles) const { return numCycles * clock; } 53 54 protected: 55 Tick intrDelay; 56 Tick intrTick; 57 bool cpuIntrEnable; 58 bool cpuPendingIntr; 59 void cpuIntrPost(Tick when); 60 void cpuInterrupt(); 61 void cpuIntrClear(); 62 63 typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent; 64 friend void IntrEvent::process(); 65 IntrEvent *intrEvent; 66 Interface *interface; 67 68 bool cpuIntrPending() const; 69 void cpuIntrAck() { cpuIntrClear(); } 70 71/** 72 * Serialization stuff 73 */ 74 public: 75 virtual void serialize(std::ostream &os); 76 virtual void unserialize(Checkpoint *cp, const std::string §ion); 77 78/** 79 * Construction/Destruction/Parameters 80 */ 81 public: 82 struct Params : public PciDev::Params 83 { 84 Tick clock; 85 Tick intr_delay; 86 }; 87 88 Base(Params *p); 89}; 90 91class Device : public Base 92{ 93 protected: 94 Platform *plat; 95 PhysicalMemory *physmem; 96 97 protected: 98 /** Receive State Machine States */ 99 enum RxState { 100 rxIdle, 101 rxFifoBlock, 102 rxBeginCopy, 103 rxCopy, 104 rxCopyDone 105 }; 106 107 /** Transmit State Machine states */ 108 enum TxState { 109 txIdle, 110 txFifoBlock, 111 txBeginCopy, 112 txCopy, 113 txCopyDone 114 }; 115 116 /** device register file */ 117 struct { 118 uint32_t Config; // 0x00 119 uint32_t Command; // 0x04 120 uint32_t IntrStatus; // 0x08 121 uint32_t IntrMask; // 0x0c 122 uint32_t RxMaxCopy; // 0x10 123 uint32_t TxMaxCopy; // 0x14 124 uint32_t RxMaxIntr; // 0x18 125 uint32_t VirtualCount; // 0x1c 126 uint32_t RxFifoSize; // 0x20 127 uint32_t TxFifoSize; // 0x24 128 uint32_t RxFifoMark; // 0x28 129 uint32_t TxFifoMark; // 0x2c 130 uint64_t RxData; // 0x30 131 uint64_t RxDone; // 0x38 132 uint64_t RxWait; // 0x40 133 uint64_t TxData; // 0x48 134 uint64_t TxDone; // 0x50 135 uint64_t TxWait; // 0x58 136 uint64_t HwAddr; // 0x60 137 } regs; 138 139 struct VirtualReg { 140 uint64_t RxData; 141 uint64_t RxDone; 142 uint64_t TxData; 143 uint64_t TxDone; 144 145 PacketFifo::iterator rxPacket; 146 int rxPacketOffset; 147 int rxPacketBytes; 148 uint64_t rxDoneData; 149 150 Counter rxUnique; 151 Counter txUnique; 152 153 VirtualReg() 154 : RxData(0), RxDone(0), TxData(0), TxDone(0), 155 rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) 156 { } 157 }; 158 typedef std::vector<VirtualReg> VirtualRegs; 159 typedef std::list<int> VirtualList; 160 Counter rxUnique; 161 Counter txUnique; 162 VirtualRegs virtualRegs; 163 VirtualList rxList; 164 VirtualList rxBusy; 165 int rxActive; 166 VirtualList txList; 167 168 uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } 169 uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } 170 uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } 171 172 private: 173 Addr addr; 174 static const Addr size = Regs::Size; 175 176 protected: 177 RxState rxState; 178 PacketFifo rxFifo; 179 PacketFifo::iterator rxFifoPtr; 180 bool rxEmpty; 181 bool rxLow; 182 Addr rxDmaAddr; 183 uint8_t *rxDmaData; 184 int rxDmaLen; 185 186 TxState txState; 187 PacketFifo txFifo; 188 bool txFull; 189 PacketPtr txPacket; 190 int txPacketOffset; 191 int txPacketBytes; 192 Addr txDmaAddr; 193 uint8_t *txDmaData; 194 int txDmaLen; 195 196 protected: 197 void reset(); 198 199 void rxKick(); 200 Tick rxKickTick; 201 typedef EventWrapper<Device, &Device::rxKick> RxKickEvent; 202 friend void RxKickEvent::process(); 203 204 void txKick(); 205 Tick txKickTick; 206 typedef EventWrapper<Device, &Device::txKick> TxKickEvent; 207 friend void TxKickEvent::process(); 208 209 /** 210 * Retransmit event 211 */ 212 void transmit(); 213 void txEventTransmit() 214 { 215 transmit(); 216 if (txState == txFifoBlock) 217 txKick(); 218 } 219 typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent; 220 friend void TxEvent::process(); 221 TxEvent txEvent; 222 223 void txDump() const; 224 void rxDump() const; 225 226 /** 227 * receive address filter 228 */ 229 bool rxFilter(const PacketPtr &packet); 230 231/** 232 * device configuration 233 */ 234 void changeConfig(uint32_t newconfig); 235 void command(uint32_t command); 236 237/** 238 * device ethernet interface 239 */ 240 public: 241 bool recvPacket(PacketPtr packet); 242 void transferDone(); 243 void setInterface(Interface *i) { assert(!interface); interface = i; } 244 245/** 246 * DMA parameters 247 */ 248 protected: 249 void rxDmaCopy(); 250 void rxDmaDone(); 251 friend class EventWrapper<Device, &Device::rxDmaDone>; 252 EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent; 253 254 void txDmaCopy(); 255 void txDmaDone(); 256 friend class EventWrapper<Device, &Device::txDmaDone>; 257 EventWrapper<Device, &Device::txDmaDone> txDmaEvent; 258 259 Tick dmaReadDelay; 260 Tick dmaReadFactor; 261 Tick dmaWriteDelay; 262 Tick dmaWriteFactor; 263 264/** 265 * Interrupt management 266 */ 267 protected: 268 void devIntrPost(uint32_t interrupts); 269 void devIntrClear(uint32_t interrupts = Regs::Intr_All); 270 void devIntrChangeMask(uint32_t newmask); 271 272/** 273 * PCI Configuration interface 274 */ 275 public: 276 virtual void writeConfig(int offset, int size, const uint8_t *data); 277 278/** 279 * Memory Interface 280 */ 281 public: 282 virtual Fault read(MemReqPtr &req, uint8_t *data); 283 virtual Fault write(MemReqPtr &req, const uint8_t *data); 284 285 void prepareIO(int cpu, int index); 286 void prepareRead(int cpu, int index); 287 void prepareWrite(int cpu, int index); 288 Fault iprRead(Addr daddr, int cpu, uint64_t &result); 289 Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); 290 Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); 291 Tick cacheAccess(MemReqPtr &req); 292 293/** 294 * Statistics 295 */ 296 private: 297 Stats::Scalar<> rxBytes; 298 Stats::Formula rxBandwidth; 299 Stats::Scalar<> rxPackets; 300 Stats::Formula rxPacketRate; 301 Stats::Scalar<> rxIpPackets; 302 Stats::Scalar<> rxTcpPackets; 303 Stats::Scalar<> rxUdpPackets; 304 Stats::Scalar<> rxIpChecksums; 305 Stats::Scalar<> rxTcpChecksums; 306 Stats::Scalar<> rxUdpChecksums; 307 308 Stats::Scalar<> txBytes; 309 Stats::Formula txBandwidth; 310 Stats::Formula totBandwidth; 311 Stats::Formula totPackets; 312 Stats::Formula totBytes; 313 Stats::Formula totPacketRate; 314 Stats::Scalar<> txPackets; 315 Stats::Formula txPacketRate; 316 Stats::Scalar<> txIpPackets; 317 Stats::Scalar<> txTcpPackets; 318 Stats::Scalar<> txUdpPackets; 319 Stats::Scalar<> txIpChecksums; 320 Stats::Scalar<> txTcpChecksums; 321 Stats::Scalar<> txUdpChecksums; 322 323 public: 324 virtual void regStats(); 325 326/** 327 * Serialization stuff 328 */ 329 public: 330 virtual void serialize(std::ostream &os); 331 virtual void unserialize(Checkpoint *cp, const std::string §ion); 332 333/** 334 * Construction/Destruction/Parameters 335 */ 336 public: 337 struct Params : public Base::Params 338 { 339 IntrControl *i; 340 PhysicalMemory *pmem; 341 Tick tx_delay; 342 Tick rx_delay; 343 HierParams *hier; 344 Bus *pio_bus; 345 Bus *header_bus; 346 Bus *payload_bus; 347 Tick pio_latency; 348 PhysicalMemory *physmem; 349 IntrControl *intctrl; 350 bool rx_filter; 351 Net::EthAddr eaddr; 352 uint32_t rx_max_copy; 353 uint32_t tx_max_copy; 354 uint32_t rx_max_intr; 355 uint32_t rx_fifo_size; 356 uint32_t tx_fifo_size; 357 uint32_t rx_fifo_threshold; 358 uint32_t rx_fifo_low_mark; 359 uint32_t tx_fifo_high_mark; 360 uint32_t tx_fifo_threshold; 361 Tick dma_read_delay; 362 Tick dma_read_factor; 363 Tick dma_write_delay; 364 Tick dma_write_factor; 365 bool dma_no_allocate; 366 bool rx_thread; 367 bool tx_thread; 368 bool rss; 369 uint32_t virtual_count; 370 bool zero_copy; 371 bool delay_copy; 372 bool virtual_addr; 373 }; 374 375 protected: 376 const Params *params() const { return (const Params *)_params; } 377 378 public: 379 Device(Params *params); 380 ~Device(); 381}; 382 383/* 384 * Ethernet Interface for an Ethernet Device 385 */ 386class Interface : public EtherInt 387{ 388 private: 389 Device *dev; 390 391 public: 392 Interface(const std::string &name, Device *d) 393 : EtherInt(name), dev(d) { dev->setInterface(this); } 394 395 virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); } 396 virtual void sendDone() { dev->transferDone(); } 397}; 398 399/* namespace Sinic */ } 400 401#endif // __DEV_SINIC_HH__ 402