sinic.hh revision 2008
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 Reserved0; // 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 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 VirtualRegs virtualRegs; 158 VirtualList rxList; 159 VirtualList txList; 160 161 uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } 162 uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } 163 uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } 164 165 private: 166 Addr addr; 167 static const Addr size = Regs::Size; 168 169 protected: 170 RxState rxState; 171 PacketFifo rxFifo; 172 PacketFifo::iterator rxFifoPtr; 173 bool rxEmpty; 174 Addr rxDmaAddr; 175 uint8_t *rxDmaData; 176 int rxDmaLen; 177 178 TxState txState; 179 PacketFifo txFifo; 180 bool txFull; 181 PacketPtr txPacket; 182 int txPacketOffset; 183 int txPacketBytes; 184 Addr txDmaAddr; 185 uint8_t *txDmaData; 186 int txDmaLen; 187 188 protected: 189 void reset(); 190 191 void rxKick(); 192 Tick rxKickTick; 193 typedef EventWrapper<Device, &Device::rxKick> RxKickEvent; 194 friend void RxKickEvent::process(); 195 196 void txKick(); 197 Tick txKickTick; 198 typedef EventWrapper<Device, &Device::txKick> TxKickEvent; 199 friend void TxKickEvent::process(); 200 201 /** 202 * Retransmit event 203 */ 204 void transmit(); 205 void txEventTransmit() 206 { 207 transmit(); 208 if (txState == txFifoBlock) 209 txKick(); 210 } 211 typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent; 212 friend void TxEvent::process(); 213 TxEvent txEvent; 214 215 void txDump() const; 216 void rxDump() const; 217 218 /** 219 * receive address filter 220 */ 221 bool rxFilter(const PacketPtr &packet); 222 223/** 224 * device configuration 225 */ 226 void changeConfig(uint32_t newconfig); 227 void command(uint32_t command); 228 229/** 230 * device ethernet interface 231 */ 232 public: 233 bool recvPacket(PacketPtr packet); 234 void transferDone(); 235 void setInterface(Interface *i) { assert(!interface); interface = i; } 236 237/** 238 * DMA parameters 239 */ 240 protected: 241 void rxDmaCopy(); 242 void rxDmaDone(); 243 friend class EventWrapper<Device, &Device::rxDmaDone>; 244 EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent; 245 246 void txDmaCopy(); 247 void txDmaDone(); 248 friend class EventWrapper<Device, &Device::txDmaDone>; 249 EventWrapper<Device, &Device::txDmaDone> txDmaEvent; 250 251 Tick dmaReadDelay; 252 Tick dmaReadFactor; 253 Tick dmaWriteDelay; 254 Tick dmaWriteFactor; 255 256/** 257 * Interrupt management 258 */ 259 protected: 260 void devIntrPost(uint32_t interrupts); 261 void devIntrClear(uint32_t interrupts = Regs::Intr_All); 262 void devIntrChangeMask(uint32_t newmask); 263 264/** 265 * PCI Configuration interface 266 */ 267 public: 268 virtual void writeConfig(int offset, int size, const uint8_t *data); 269 270/** 271 * Memory Interface 272 */ 273 public: 274 virtual Fault read(MemReqPtr &req, uint8_t *data); 275 virtual Fault write(MemReqPtr &req, const uint8_t *data); 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 Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); 282 Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); 283 void regWrite(Addr daddr, int cpu, const uint8_t *data); 284 Tick cacheAccess(MemReqPtr &req); 285 286 protected: 287 struct RegWriteData { 288 Addr daddr; 289 uint64_t value; 290 RegWriteData(Addr da, uint64_t val) : daddr(da), value(val) {} 291 }; 292 293 std::vector<std::list<RegWriteData> > writeQueue; 294 295 bool pioDelayWrite; 296 297/** 298 * Statistics 299 */ 300 private: 301 Stats::Scalar<> rxBytes; 302 Stats::Formula rxBandwidth; 303 Stats::Scalar<> rxPackets; 304 Stats::Formula rxPacketRate; 305 Stats::Scalar<> rxIpPackets; 306 Stats::Scalar<> rxTcpPackets; 307 Stats::Scalar<> rxUdpPackets; 308 Stats::Scalar<> rxIpChecksums; 309 Stats::Scalar<> rxTcpChecksums; 310 Stats::Scalar<> rxUdpChecksums; 311 312 Stats::Scalar<> txBytes; 313 Stats::Formula txBandwidth; 314 Stats::Formula totBandwidth; 315 Stats::Formula totPackets; 316 Stats::Formula totBytes; 317 Stats::Formula totPacketRate; 318 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