sinic.hh revision 4762
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 "params/Sinic.hh" 43#include "params/SinicInt.hh" 44#include "sim/eventq.hh" 45 46namespace Sinic { 47 48class Interface; 49class Base : public PciDev 50{ 51 protected: 52 bool rxEnable; 53 bool txEnable; 54 Tick clock; 55 inline Tick cycles(int numCycles) const { return numCycles * clock; } 56 57 protected: 58 Tick intrDelay; 59 Tick intrTick; 60 bool cpuIntrEnable; 61 bool cpuPendingIntr; 62 void cpuIntrPost(Tick when); 63 void cpuInterrupt(); 64 void cpuIntrClear(); 65 66 typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent; 67 friend void IntrEvent::process(); 68 IntrEvent *intrEvent; 69 Interface *interface; 70 71 bool cpuIntrPending() const; 72 void cpuIntrAck() { cpuIntrClear(); } 73 74/** 75 * Serialization stuff 76 */ 77 public: 78 virtual void serialize(std::ostream &os); 79 virtual void unserialize(Checkpoint *cp, const std::string §ion); 80 81/** 82 * Construction/Destruction/Parameters 83 */ 84 public: 85 typedef SinicParams Params; 86 const Params *params() const { return (const Params *)_params; } 87 Base(Params *p); 88}; 89 90class Device : public Base 91{ 92 protected: 93 /** Receive State Machine States */ 94 enum RxState { 95 rxIdle, 96 rxFifoBlock, 97 rxBeginCopy, 98 rxCopy, 99 rxCopyDone 100 }; 101 102 /** Transmit State Machine states */ 103 enum TxState { 104 txIdle, 105 txFifoBlock, 106 txBeginCopy, 107 txCopy, 108 txCopyDone 109 }; 110 111 /** device register file */ 112 struct { 113 uint32_t Config; // 0x00 114 uint32_t Command; // 0x04 115 uint32_t IntrStatus; // 0x08 116 uint32_t IntrMask; // 0x0c 117 uint32_t RxMaxCopy; // 0x10 118 uint32_t TxMaxCopy; // 0x14 119 uint32_t RxMaxIntr; // 0x18 120 uint32_t VirtualCount; // 0x1c 121 uint32_t RxFifoSize; // 0x20 122 uint32_t TxFifoSize; // 0x24 123 uint32_t RxFifoMark; // 0x28 124 uint32_t TxFifoMark; // 0x2c 125 uint64_t RxData; // 0x30 126 uint64_t RxDone; // 0x38 127 uint64_t RxWait; // 0x40 128 uint64_t TxData; // 0x48 129 uint64_t TxDone; // 0x50 130 uint64_t TxWait; // 0x58 131 uint64_t HwAddr; // 0x60 132 } regs; 133 134 struct VirtualReg { 135 uint64_t RxData; 136 uint64_t RxDone; 137 uint64_t TxData; 138 uint64_t TxDone; 139 140 PacketFifo::iterator rxPacket; 141 int rxPacketOffset; 142 int rxPacketBytes; 143 uint64_t rxDoneData; 144 145 Counter rxUnique; 146 Counter txUnique; 147 148 VirtualReg() 149 : RxData(0), RxDone(0), TxData(0), TxDone(0), 150 rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) 151 { } 152 }; 153 typedef std::vector<VirtualReg> VirtualRegs; 154 typedef std::list<int> VirtualList; 155 Counter rxUnique; 156 Counter txUnique; 157 VirtualRegs virtualRegs; 158 VirtualList rxList; 159 VirtualList rxBusy; 160 int rxActive; 161 VirtualList txList; 162 163 uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } 164 uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } 165 uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } 166 167 protected: 168 RxState rxState; 169 PacketFifo rxFifo; 170 PacketFifo::iterator rxFifoPtr; 171 bool rxEmpty; 172 bool rxLow; 173 Addr rxDmaAddr; 174 uint8_t *rxDmaData; 175 int rxDmaLen; 176 177 TxState txState; 178 PacketFifo txFifo; 179 bool txFull; 180 EthPacketPtr txPacket; 181 int txPacketOffset; 182 int txPacketBytes; 183 Addr txDmaAddr; 184 uint8_t *txDmaData; 185 int txDmaLen; 186 187 protected: 188 void reset(); 189 190 void rxKick(); 191 Tick rxKickTick; 192 typedef EventWrapper<Device, &Device::rxKick> RxKickEvent; 193 friend void RxKickEvent::process(); 194 195 void txKick(); 196 Tick txKickTick; 197 typedef EventWrapper<Device, &Device::txKick> TxKickEvent; 198 friend void TxKickEvent::process(); 199 200 /** 201 * Retransmit event 202 */ 203 void transmit(); 204 void txEventTransmit() 205 { 206 transmit(); 207 if (txState == txFifoBlock) 208 txKick(); 209 } 210 typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent; 211 friend void TxEvent::process(); 212 TxEvent txEvent; 213 214 void txDump() const; 215 void rxDump() const; 216 217 /** 218 * receive address filter 219 */ 220 bool rxFilter(const EthPacketPtr &packet); 221 222/** 223 * device configuration 224 */ 225 void changeConfig(uint32_t newconfig); 226 void command(uint32_t command); 227 228/** 229 * device ethernet interface 230 */ 231 public: 232 bool recvPacket(EthPacketPtr packet); 233 void transferDone(); 234 void setInterface(Interface *i) { assert(!interface); interface = i; } 235 236/** 237 * DMA parameters 238 */ 239 protected: 240 void rxDmaDone(); 241 friend class EventWrapper<Device, &Device::rxDmaDone>; 242 EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent; 243 244 void txDmaDone(); 245 friend class EventWrapper<Device, &Device::txDmaDone>; 246 EventWrapper<Device, &Device::txDmaDone> txDmaEvent; 247 248 Tick dmaReadDelay; 249 Tick dmaReadFactor; 250 Tick dmaWriteDelay; 251 Tick dmaWriteFactor; 252 253/** 254 * Interrupt management 255 */ 256 protected: 257 void devIntrPost(uint32_t interrupts); 258 void devIntrClear(uint32_t interrupts = Regs::Intr_All); 259 void devIntrChangeMask(uint32_t newmask); 260 261/** 262 * Memory Interface 263 */ 264 public: 265 virtual Tick read(PacketPtr pkt); 266 virtual Tick write(PacketPtr pkt); 267 virtual void resume(); 268 269 void prepareIO(int cpu, int index); 270 void prepareRead(int cpu, int index); 271 void prepareWrite(int cpu, int index); 272 // Fault iprRead(Addr daddr, int cpu, uint64_t &result); 273 274/** 275 * Statistics 276 */ 277 private: 278 Stats::Scalar<> rxBytes; 279 Stats::Formula rxBandwidth; 280 Stats::Scalar<> rxPackets; 281 Stats::Formula rxPacketRate; 282 Stats::Scalar<> rxIpPackets; 283 Stats::Scalar<> rxTcpPackets; 284 Stats::Scalar<> rxUdpPackets; 285 Stats::Scalar<> rxIpChecksums; 286 Stats::Scalar<> rxTcpChecksums; 287 Stats::Scalar<> rxUdpChecksums; 288 289 Stats::Scalar<> txBytes; 290 Stats::Formula txBandwidth; 291 Stats::Formula totBandwidth; 292 Stats::Formula totPackets; 293 Stats::Formula totBytes; 294 Stats::Formula totPacketRate; 295 Stats::Scalar<> txPackets; 296 Stats::Formula txPacketRate; 297 Stats::Scalar<> txIpPackets; 298 Stats::Scalar<> txTcpPackets; 299 Stats::Scalar<> txUdpPackets; 300 Stats::Scalar<> txIpChecksums; 301 Stats::Scalar<> txTcpChecksums; 302 Stats::Scalar<> txUdpChecksums; 303 304 public: 305 virtual void regStats(); 306 307/** 308 * Serialization stuff 309 */ 310 public: 311 virtual void serialize(std::ostream &os); 312 virtual void unserialize(Checkpoint *cp, const std::string §ion); 313 314 public: 315 Device(Params *p); 316 ~Device(); 317}; 318 319/* 320 * Ethernet Interface for an Ethernet Device 321 */ 322class Interface : public EtherInt 323{ 324 private: 325 Device *dev; 326 327 public: 328 Interface(const std::string &name, Device *d) 329 : EtherInt(name), dev(d) { dev->setInterface(this); } 330 331 virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } 332 virtual void sendDone() { dev->transferDone(); } 333}; 334 335/* namespace Sinic */ } 336 337#endif // __DEV_SINIC_HH__ 338