sinic.hh revision 4762
112653Sandreas.sandberg@arm.com/* 212653Sandreas.sandberg@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 312653Sandreas.sandberg@arm.com * All rights reserved. 412653Sandreas.sandberg@arm.com * 512653Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 612653Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 712653Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 812653Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 912653Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1012653Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1112653Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1212653Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 1312653Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 1412653Sandreas.sandberg@arm.com * this software without specific prior written permission. 1512653Sandreas.sandberg@arm.com * 1612653Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712653Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812653Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912653Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012653Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112653Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212653Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312653Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412653Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512653Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612653Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712653Sandreas.sandberg@arm.com * 2812653Sandreas.sandberg@arm.com * Authors: Nathan Binkert 2912653Sandreas.sandberg@arm.com */ 3012653Sandreas.sandberg@arm.com 3112653Sandreas.sandberg@arm.com#ifndef __DEV_SINIC_HH__ 3212653Sandreas.sandberg@arm.com#define __DEV_SINIC_HH__ 3312653Sandreas.sandberg@arm.com 3412653Sandreas.sandberg@arm.com#include "base/inet.hh" 3512653Sandreas.sandberg@arm.com#include "base/statistics.hh" 3612653Sandreas.sandberg@arm.com#include "dev/etherint.hh" 3712653Sandreas.sandberg@arm.com#include "dev/etherpkt.hh" 3812653Sandreas.sandberg@arm.com#include "dev/io_device.hh" 3912653Sandreas.sandberg@arm.com#include "dev/pcidev.hh" 4012653Sandreas.sandberg@arm.com#include "dev/pktfifo.hh" 4112653Sandreas.sandberg@arm.com#include "dev/sinicreg.hh" 4212653Sandreas.sandberg@arm.com#include "params/Sinic.hh" 4312653Sandreas.sandberg@arm.com#include "params/SinicInt.hh" 4412653Sandreas.sandberg@arm.com#include "sim/eventq.hh" 4512653Sandreas.sandberg@arm.com 4612653Sandreas.sandberg@arm.comnamespace Sinic { 4712653Sandreas.sandberg@arm.com 4812660Sandreas.sandberg@arm.comclass Interface; 4912653Sandreas.sandberg@arm.comclass Base : public PciDev 5012653Sandreas.sandberg@arm.com{ 5112653Sandreas.sandberg@arm.com protected: 5212653Sandreas.sandberg@arm.com bool rxEnable; 5312654Sandreas.sandberg@arm.com bool txEnable; 5412654Sandreas.sandberg@arm.com Tick clock; 5512653Sandreas.sandberg@arm.com inline Tick cycles(int numCycles) const { return numCycles * clock; } 5612654Sandreas.sandberg@arm.com 5712654Sandreas.sandberg@arm.com protected: 5812653Sandreas.sandberg@arm.com Tick intrDelay; 5912653Sandreas.sandberg@arm.com Tick intrTick; 6012653Sandreas.sandberg@arm.com bool cpuIntrEnable; 6112653Sandreas.sandberg@arm.com bool cpuPendingIntr; 6212653Sandreas.sandberg@arm.com void cpuIntrPost(Tick when); 6312653Sandreas.sandberg@arm.com void cpuInterrupt(); 6412654Sandreas.sandberg@arm.com void cpuIntrClear(); 6512654Sandreas.sandberg@arm.com 6612653Sandreas.sandberg@arm.com typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent; 6712653Sandreas.sandberg@arm.com friend void IntrEvent::process(); 6812653Sandreas.sandberg@arm.com IntrEvent *intrEvent; 6912653Sandreas.sandberg@arm.com Interface *interface; 7012653Sandreas.sandberg@arm.com 7112653Sandreas.sandberg@arm.com bool cpuIntrPending() const; 7212654Sandreas.sandberg@arm.com void cpuIntrAck() { cpuIntrClear(); } 7312654Sandreas.sandberg@arm.com 7412653Sandreas.sandberg@arm.com/** 7512653Sandreas.sandberg@arm.com * Serialization stuff 7612656Sandreas.sandberg@arm.com */ 7712656Sandreas.sandberg@arm.com public: 7812653Sandreas.sandberg@arm.com virtual void serialize(std::ostream &os); 7912656Sandreas.sandberg@arm.com virtual void unserialize(Checkpoint *cp, const std::string §ion); 8012660Sandreas.sandberg@arm.com 8112660Sandreas.sandberg@arm.com/** 8212660Sandreas.sandberg@arm.com * Construction/Destruction/Parameters 8312660Sandreas.sandberg@arm.com */ 8412660Sandreas.sandberg@arm.com public: 8512660Sandreas.sandberg@arm.com typedef SinicParams Params; 8612660Sandreas.sandberg@arm.com const Params *params() const { return (const Params *)_params; } 8712660Sandreas.sandberg@arm.com Base(Params *p); 8812660Sandreas.sandberg@arm.com}; 8912660Sandreas.sandberg@arm.com 9012660Sandreas.sandberg@arm.comclass Device : public Base 9112660Sandreas.sandberg@arm.com{ 9212660Sandreas.sandberg@arm.com protected: 9312660Sandreas.sandberg@arm.com /** Receive State Machine States */ 9412660Sandreas.sandberg@arm.com enum RxState { 9512660Sandreas.sandberg@arm.com rxIdle, 9612660Sandreas.sandberg@arm.com rxFifoBlock, 9712660Sandreas.sandberg@arm.com rxBeginCopy, 9812660Sandreas.sandberg@arm.com rxCopy, 9912660Sandreas.sandberg@arm.com rxCopyDone 10012660Sandreas.sandberg@arm.com }; 10112660Sandreas.sandberg@arm.com 10212660Sandreas.sandberg@arm.com /** Transmit State Machine states */ 10312660Sandreas.sandberg@arm.com enum TxState { 10412660Sandreas.sandberg@arm.com txIdle, 10512660Sandreas.sandberg@arm.com txFifoBlock, 10612660Sandreas.sandberg@arm.com txBeginCopy, 10712660Sandreas.sandberg@arm.com txCopy, 10812660Sandreas.sandberg@arm.com txCopyDone 10912660Sandreas.sandberg@arm.com }; 11012656Sandreas.sandberg@arm.com 11112656Sandreas.sandberg@arm.com /** device register file */ 11212656Sandreas.sandberg@arm.com struct { 11312656Sandreas.sandberg@arm.com uint32_t Config; // 0x00 11412656Sandreas.sandberg@arm.com uint32_t Command; // 0x04 11512653Sandreas.sandberg@arm.com uint32_t IntrStatus; // 0x08 11612653Sandreas.sandberg@arm.com uint32_t IntrMask; // 0x0c 11712656Sandreas.sandberg@arm.com uint32_t RxMaxCopy; // 0x10 11812656Sandreas.sandberg@arm.com uint32_t TxMaxCopy; // 0x14 11912656Sandreas.sandberg@arm.com uint32_t RxMaxIntr; // 0x18 12012653Sandreas.sandberg@arm.com uint32_t VirtualCount; // 0x1c 12112656Sandreas.sandberg@arm.com uint32_t RxFifoSize; // 0x20 12212653Sandreas.sandberg@arm.com uint32_t TxFifoSize; // 0x24 12312660Sandreas.sandberg@arm.com uint32_t RxFifoMark; // 0x28 12412653Sandreas.sandberg@arm.com uint32_t TxFifoMark; // 0x2c 12512660Sandreas.sandberg@arm.com uint64_t RxData; // 0x30 12612653Sandreas.sandberg@arm.com uint64_t RxDone; // 0x38 12712660Sandreas.sandberg@arm.com uint64_t RxWait; // 0x40 12812656Sandreas.sandberg@arm.com uint64_t TxData; // 0x48 12912656Sandreas.sandberg@arm.com uint64_t TxDone; // 0x50 13012656Sandreas.sandberg@arm.com uint64_t TxWait; // 0x58 13112656Sandreas.sandberg@arm.com uint64_t HwAddr; // 0x60 13212656Sandreas.sandberg@arm.com } regs; 13312656Sandreas.sandberg@arm.com 13412656Sandreas.sandberg@arm.com struct VirtualReg { 13512656Sandreas.sandberg@arm.com uint64_t RxData; 13612656Sandreas.sandberg@arm.com uint64_t RxDone; 13712660Sandreas.sandberg@arm.com uint64_t TxData; 13812653Sandreas.sandberg@arm.com uint64_t TxDone; 13912660Sandreas.sandberg@arm.com 14012653Sandreas.sandberg@arm.com PacketFifo::iterator rxPacket; 14112660Sandreas.sandberg@arm.com int rxPacketOffset; 14212653Sandreas.sandberg@arm.com int rxPacketBytes; 14312660Sandreas.sandberg@arm.com uint64_t rxDoneData; 14412653Sandreas.sandberg@arm.com 14512653Sandreas.sandberg@arm.com Counter rxUnique; 14612660Sandreas.sandberg@arm.com Counter txUnique; 14712653Sandreas.sandberg@arm.com 14812660Sandreas.sandberg@arm.com VirtualReg() 14912653Sandreas.sandberg@arm.com : RxData(0), RxDone(0), TxData(0), TxDone(0), 15012660Sandreas.sandberg@arm.com rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) 15112653Sandreas.sandberg@arm.com { } 15212653Sandreas.sandberg@arm.com }; 15312656Sandreas.sandberg@arm.com typedef std::vector<VirtualReg> VirtualRegs; 15412653Sandreas.sandberg@arm.com typedef std::list<int> VirtualList; 15512653Sandreas.sandberg@arm.com Counter rxUnique; 15612653Sandreas.sandberg@arm.com Counter txUnique; 15712654Sandreas.sandberg@arm.com VirtualRegs virtualRegs; 15812654Sandreas.sandberg@arm.com VirtualList rxList; 15912654Sandreas.sandberg@arm.com VirtualList rxBusy; 16012654Sandreas.sandberg@arm.com int rxActive; 16112654Sandreas.sandberg@arm.com VirtualList txList; 16212654Sandreas.sandberg@arm.com 16312654Sandreas.sandberg@arm.com uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } 16412654Sandreas.sandberg@arm.com uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } 16512654Sandreas.sandberg@arm.com uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } 16612654Sandreas.sandberg@arm.com 16712654Sandreas.sandberg@arm.com protected: 16812654Sandreas.sandberg@arm.com RxState rxState; 16912654Sandreas.sandberg@arm.com PacketFifo rxFifo; 17012654Sandreas.sandberg@arm.com PacketFifo::iterator rxFifoPtr; 17112654Sandreas.sandberg@arm.com bool rxEmpty; 17212654Sandreas.sandberg@arm.com bool rxLow; 17312654Sandreas.sandberg@arm.com Addr rxDmaAddr; 17412654Sandreas.sandberg@arm.com uint8_t *rxDmaData; 17512654Sandreas.sandberg@arm.com int rxDmaLen; 17612654Sandreas.sandberg@arm.com 17712654Sandreas.sandberg@arm.com TxState txState; 17812653Sandreas.sandberg@arm.com PacketFifo txFifo; 17912653Sandreas.sandberg@arm.com bool txFull; 18012653Sandreas.sandberg@arm.com EthPacketPtr txPacket; 18112653Sandreas.sandberg@arm.com int txPacketOffset; 18212653Sandreas.sandberg@arm.com 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