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_NET_SINIC_HH__ 32#define __DEV_NET_SINIC_HH__ 33 34#include "base/inet.hh" 35#include "base/statistics.hh" 36#include "dev/io_device.hh" 37#include "dev/net/etherdevice.hh" 38#include "dev/net/etherint.hh" 39#include "dev/net/etherpkt.hh" 40#include "dev/net/pktfifo.hh" 41#include "dev/net/sinicreg.hh" 42#include "dev/pci/device.hh" 43#include "params/Sinic.hh" 44#include "sim/eventq.hh" 45 46namespace Sinic { 47 48class Interface; 49class Base : public EtherDevBase 50{ 51 protected: 52 bool rxEnable; 53 bool txEnable; 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 EventFunctionWrapper *intrEvent; 65 Interface *interface; 66 67 bool cpuIntrPending() const; 68 void cpuIntrAck() { cpuIntrClear(); } 69 70/** 71 * Serialization stuff 72 */ 73 public: 74 void serialize(CheckpointOut &cp) const override; 75 void unserialize(CheckpointIn &cp) override; 76 77/** 78 * Construction/Destruction/Parameters 79 */ 80 public: 81 typedef SinicParams Params; 82 const Params *params() const { return (const Params *)_params; } 83 Base(const Params *p); 84}; 85 86class Device : public Base 87{ 88 protected: 89 /** Receive State Machine States */ 90 enum RxState { 91 rxIdle, 92 rxFifoBlock, 93 rxBeginCopy, 94 rxCopy, 95 rxCopyDone 96 }; 97 98 /** Transmit State Machine states */ 99 enum TxState { 100 txIdle, 101 txFifoBlock, 102 txBeginCopy, 103 txCopy, 104 txCopyDone 105 }; 106 107 /** device register file */ 108 struct { 109 uint32_t Config; // 0x00 110 uint32_t Command; // 0x04 111 uint32_t IntrStatus; // 0x08 112 uint32_t IntrMask; // 0x0c 113 uint32_t RxMaxCopy; // 0x10 114 uint32_t TxMaxCopy; // 0x14 115 uint32_t ZeroCopySize; // 0x18 116 uint32_t ZeroCopyMark; // 0x1c 117 uint32_t VirtualCount; // 0x20 118 uint32_t RxMaxIntr; // 0x24 119 uint32_t RxFifoSize; // 0x28 120 uint32_t TxFifoSize; // 0x2c 121 uint32_t RxFifoLow; // 0x30 122 uint32_t TxFifoLow; // 0x34 123 uint32_t RxFifoHigh; // 0x38 124 uint32_t TxFifoHigh; // 0x3c 125 uint64_t RxData; // 0x40 126 uint64_t RxDone; // 0x48 127 uint64_t RxWait; // 0x50 128 uint64_t TxData; // 0x58 129 uint64_t TxDone; // 0x60 130 uint64_t TxWait; // 0x68 131 uint64_t HwAddr; // 0x70 132 uint64_t RxStatus; // 0x78 133 } regs; 134 135 struct VirtualReg { 136 uint64_t RxData; 137 uint64_t RxDone; 138 uint64_t TxData; 139 uint64_t TxDone; 140 141 PacketFifo::iterator rxIndex; 142 unsigned rxPacketOffset; 143 unsigned rxPacketBytes; 144 uint64_t rxDoneData; 145 146 Counter rxUnique; 147 Counter txUnique; 148 149 VirtualReg() 150 : RxData(0), RxDone(0), TxData(0), TxDone(0), 151 rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) 152 { } 153 }; 154 typedef std::vector<VirtualReg> VirtualRegs; 155 typedef std::list<unsigned> VirtualList; 156 Counter rxUnique; 157 Counter txUnique; 158 VirtualRegs virtualRegs; 159 VirtualList rxList; 160 VirtualList rxBusy; 161 int rxActive; 162 VirtualList txList; 163 164 int rxBusyCount; 165 int rxMappedCount; 166 int rxDirtyCount; 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 protected: 173 RxState rxState; 174 PacketFifo rxFifo; 175 PacketFifo::iterator rxFifoPtr; 176 bool rxEmpty; 177 bool rxLow; 178 Addr rxDmaAddr; 179 uint8_t *rxDmaData; 180 unsigned rxDmaLen; 181 182 TxState txState; 183 PacketFifo txFifo; 184 bool txFull; 185 EthPacketPtr txPacket; 186 int txPacketOffset; 187 int txPacketBytes; 188 Addr txDmaAddr; 189 uint8_t *txDmaData; 190 int txDmaLen; 191 192 protected: 193 void reset(); 194 195 void rxKick(); 196 Tick rxKickTick; 197 198 void txKick(); 199 Tick txKickTick; 200 201 /** 202 * Retransmit event 203 */ 204 void transmit(); 205 void txEventTransmit() 206 { 207 transmit(); 208 if (txState == txFifoBlock) 209 txKick(); 210 } 211 EventFunctionWrapper txEvent; 212 213 void txDump() const; 214 void rxDump() const; 215 216 /** 217 * receive address filter 218 */ 219 bool rxFilter(const EthPacketPtr &packet); 220 221/** 222 * device configuration 223 */ 224 void changeConfig(uint32_t newconfig); 225 void command(uint32_t command); 226 227/** 228 * device ethernet interface 229 */ 230 public: 231 bool recvPacket(EthPacketPtr packet); 232 void transferDone(); 233 Port &getPort(const std::string &if_name, 234 PortID idx=InvalidPortID) override; 235 236/** 237 * DMA parameters 238 */ 239 protected: 240 void rxDmaDone(); 241 EventFunctionWrapper rxDmaEvent; 242 243 void txDmaDone(); 244 EventFunctionWrapper txDmaEvent; 245 246 Tick dmaReadDelay; 247 Tick dmaReadFactor; 248 Tick dmaWriteDelay; 249 Tick dmaWriteFactor; 250 251/** 252 * Interrupt management 253 */ 254 protected: 255 void devIntrPost(uint32_t interrupts); 256 void devIntrClear(uint32_t interrupts = Regs::Intr_All); 257 void devIntrChangeMask(uint32_t newmask); 258 259/** 260 * Memory Interface 261 */ 262 public: 263 Tick read(PacketPtr pkt) override; 264 Tick write(PacketPtr pkt) override; 265 virtual void drainResume() override; 266 267 void prepareIO(ContextID cpu, int index); 268 void prepareRead(ContextID cpu, int index); 269 void prepareWrite(ContextID cpu, int index); 270 // Fault iprRead(Addr daddr, ContextID cpu, uint64_t &result); 271 272/** 273 * Statistics 274 */ 275 private: 276 Stats::Scalar totalVnicDistance; 277 Stats::Scalar numVnicDistance; 278 Stats::Scalar maxVnicDistance; 279 Stats::Formula avgVnicDistance; 280 281 int _maxVnicDistance; 282 283 public: 284 void regStats() override; 285 void resetStats() override; 286 287/** 288 * Serialization stuff 289 */ 290 public: 291 void serialize(CheckpointOut &cp) const override; 292 void unserialize(CheckpointIn &cp) override; 293 294 public: 295 Device(const Params *p); 296 ~Device(); 297}; 298 299/* 300 * Ethernet Interface for an Ethernet Device 301 */ 302class Interface : public EtherInt 303{ 304 private: 305 Device *dev; 306 307 public: 308 Interface(const std::string &name, Device *d) 309 : EtherInt(name), dev(d) 310 { } 311 312 virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } 313 virtual void sendDone() { dev->transferDone(); } 314}; 315 316} // namespace Sinic 317 318#endif // __DEV_NET_SINIC_HH__ 319