Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 1 | /* |
Steve Reinhardt | ad8b963 | 2005-06-05 05:16:00 -0400 | [diff] [blame] | 2 | * Copyright (c) 2004-2005 The Regents of The University of Michigan |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 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. |
Ali Saidi | cb0cf2d | 2006-05-31 19:26:56 -0400 | [diff] [blame] | 27 | * |
| 28 | * Authors: Nathan Binkert |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 29 | */ |
| 30 | |
Andreas Sandberg | 23c961a | 2015-12-10 10:35:18 +0000 | [diff] [blame] | 31 | #ifndef __DEV_NET_SINIC_HH__ |
| 32 | #define __DEV_NET_SINIC_HH__ |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 33 | |
| 34 | #include "base/inet.hh" |
| 35 | #include "base/statistics.hh" |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 36 | #include "dev/io_device.hh" |
Andreas Sandberg | 23c961a | 2015-12-10 10:35:18 +0000 | [diff] [blame] | 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" |
Andreas Sandberg | 139c97c | 2015-12-10 10:35:15 +0000 | [diff] [blame] | 42 | #include "dev/pci/device.hh" |
Nathan Binkert | abc76f2 | 2007-07-23 21:51:38 -0700 | [diff] [blame] | 43 | #include "params/Sinic.hh" |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 44 | #include "sim/eventq.hh" |
| 45 | |
| 46 | namespace Sinic { |
| 47 | |
| 48 | class Interface; |
Andreas Sandberg | df02047 | 2012-11-02 11:32:01 -0500 | [diff] [blame] | 49 | class Base : public EtherDevBase |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 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 | |
Sean Wilson | c8668a6 | 2017-06-07 16:32:15 -0500 | [diff] [blame] | 64 | EventFunctionWrapper *intrEvent; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 65 | Interface *interface; |
| 66 | |
| 67 | bool cpuIntrPending() const; |
| 68 | void cpuIntrAck() { cpuIntrClear(); } |
| 69 | |
| 70 | /** |
| 71 | * Serialization stuff |
| 72 | */ |
| 73 | public: |
Andreas Hansson | 22c0419 | 2015-10-12 04:07:59 -0400 | [diff] [blame] | 74 | void serialize(CheckpointOut &cp) const override; |
| 75 | void unserialize(CheckpointIn &cp) override; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 76 | |
| 77 | /** |
| 78 | * Construction/Destruction/Parameters |
| 79 | */ |
| 80 | public: |
Nathan Binkert | abc76f2 | 2007-07-23 21:51:38 -0700 | [diff] [blame] | 81 | typedef SinicParams Params; |
| 82 | const Params *params() const { return (const Params *)_params; } |
Ali Saidi | 773cb77 | 2007-08-16 16:49:02 -0400 | [diff] [blame] | 83 | Base(const Params *p); |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 84 | }; |
| 85 | |
| 86 | class Device : public Base |
| 87 | { |
| 88 | protected: |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 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 { |
Nathan Binkert | b7b8ffa | 2005-10-21 20:28:21 -0400 | [diff] [blame] | 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 |
Nathan Binkert | 886c5f8 | 2008-10-09 04:58:23 -0700 | [diff] [blame] | 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 |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 133 | } regs; |
| 134 | |
Nathan Binkert | 47ff0af | 2005-11-25 13:33:36 -0500 | [diff] [blame] | 135 | struct VirtualReg { |
| 136 | uint64_t RxData; |
| 137 | uint64_t RxDone; |
| 138 | uint64_t TxData; |
| 139 | uint64_t TxDone; |
| 140 | |
Nathan Binkert | 886c5f8 | 2008-10-09 04:58:23 -0700 | [diff] [blame] | 141 | PacketFifo::iterator rxIndex; |
Nathan Binkert | 6faf377 | 2009-06-04 23:21:12 -0700 | [diff] [blame] | 142 | unsigned rxPacketOffset; |
| 143 | unsigned rxPacketBytes; |
Nathan Binkert | 47ff0af | 2005-11-25 13:33:36 -0500 | [diff] [blame] | 144 | uint64_t rxDoneData; |
| 145 | |
Nathan Binkert | 8e9d444 | 2006-04-26 17:52:33 -0400 | [diff] [blame] | 146 | Counter rxUnique; |
| 147 | Counter txUnique; |
| 148 | |
Nathan Binkert | 47ff0af | 2005-11-25 13:33:36 -0500 | [diff] [blame] | 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; |
Nathan Binkert | 6faf377 | 2009-06-04 23:21:12 -0700 | [diff] [blame] | 155 | typedef std::list<unsigned> VirtualList; |
Nathan Binkert | 8e9d444 | 2006-04-26 17:52:33 -0400 | [diff] [blame] | 156 | Counter rxUnique; |
| 157 | Counter txUnique; |
Nathan Binkert | 47ff0af | 2005-11-25 13:33:36 -0500 | [diff] [blame] | 158 | VirtualRegs virtualRegs; |
| 159 | VirtualList rxList; |
Nathan Binkert | 8e9d444 | 2006-04-26 17:52:33 -0400 | [diff] [blame] | 160 | VirtualList rxBusy; |
| 161 | int rxActive; |
Nathan Binkert | 47ff0af | 2005-11-25 13:33:36 -0500 | [diff] [blame] | 162 | VirtualList txList; |
| 163 | |
Nathan Binkert | 886c5f8 | 2008-10-09 04:58:23 -0700 | [diff] [blame] | 164 | int rxBusyCount; |
| 165 | int rxMappedCount; |
| 166 | int rxDirtyCount; |
| 167 | |
Nathan Binkert | b7b8ffa | 2005-10-21 20:28:21 -0400 | [diff] [blame] | 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 | |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 172 | protected: |
| 173 | RxState rxState; |
| 174 | PacketFifo rxFifo; |
Nathan Binkert | 47ff0af | 2005-11-25 13:33:36 -0500 | [diff] [blame] | 175 | PacketFifo::iterator rxFifoPtr; |
Nathan Binkert | b7b8ffa | 2005-10-21 20:28:21 -0400 | [diff] [blame] | 176 | bool rxEmpty; |
Nathan Binkert | 8e9d444 | 2006-04-26 17:52:33 -0400 | [diff] [blame] | 177 | bool rxLow; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 178 | Addr rxDmaAddr; |
| 179 | uint8_t *rxDmaData; |
Nathan Binkert | 6faf377 | 2009-06-04 23:21:12 -0700 | [diff] [blame] | 180 | unsigned rxDmaLen; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 181 | |
| 182 | TxState txState; |
| 183 | PacketFifo txFifo; |
Nathan Binkert | b7b8ffa | 2005-10-21 20:28:21 -0400 | [diff] [blame] | 184 | bool txFull; |
Ali Saidi | 8f8d095 | 2006-04-24 19:31:50 -0400 | [diff] [blame] | 185 | EthPacketPtr txPacket; |
Nathan Binkert | 47ff0af | 2005-11-25 13:33:36 -0500 | [diff] [blame] | 186 | int txPacketOffset; |
| 187 | int txPacketBytes; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 188 | Addr txDmaAddr; |
| 189 | uint8_t *txDmaData; |
| 190 | int txDmaLen; |
| 191 | |
| 192 | protected: |
| 193 | void reset(); |
| 194 | |
| 195 | void rxKick(); |
| 196 | Tick rxKickTick; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 197 | |
| 198 | void txKick(); |
| 199 | Tick txKickTick; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 200 | |
| 201 | /** |
| 202 | * Retransmit event |
| 203 | */ |
| 204 | void transmit(); |
| 205 | void txEventTransmit() |
| 206 | { |
| 207 | transmit(); |
| 208 | if (txState == txFifoBlock) |
| 209 | txKick(); |
| 210 | } |
Sean Wilson | c8668a6 | 2017-06-07 16:32:15 -0500 | [diff] [blame] | 211 | EventFunctionWrapper txEvent; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 212 | |
| 213 | void txDump() const; |
| 214 | void rxDump() const; |
| 215 | |
| 216 | /** |
| 217 | * receive address filter |
| 218 | */ |
Ali Saidi | 8f8d095 | 2006-04-24 19:31:50 -0400 | [diff] [blame] | 219 | bool rxFilter(const EthPacketPtr &packet); |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 220 | |
| 221 | /** |
| 222 | * device configuration |
| 223 | */ |
| 224 | void changeConfig(uint32_t newconfig); |
Nathan Binkert | b7b8ffa | 2005-10-21 20:28:21 -0400 | [diff] [blame] | 225 | void command(uint32_t command); |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 226 | |
| 227 | /** |
| 228 | * device ethernet interface |
| 229 | */ |
| 230 | public: |
Ali Saidi | 8f8d095 | 2006-04-24 19:31:50 -0400 | [diff] [blame] | 231 | bool recvPacket(EthPacketPtr packet); |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 232 | void transferDone(); |
Andreas Hansson | 2ac04c1 | 2015-10-12 04:08:01 -0400 | [diff] [blame] | 233 | EtherInt *getEthPort(const std::string &if_name, int idx) override; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 234 | |
| 235 | /** |
| 236 | * DMA parameters |
| 237 | */ |
| 238 | protected: |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 239 | void rxDmaDone(); |
Sean Wilson | c8668a6 | 2017-06-07 16:32:15 -0500 | [diff] [blame] | 240 | EventFunctionWrapper rxDmaEvent; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 241 | |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 242 | void txDmaDone(); |
Sean Wilson | c8668a6 | 2017-06-07 16:32:15 -0500 | [diff] [blame] | 243 | EventFunctionWrapper txDmaEvent; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 244 | |
| 245 | Tick dmaReadDelay; |
| 246 | Tick dmaReadFactor; |
| 247 | Tick dmaWriteDelay; |
| 248 | Tick dmaWriteFactor; |
| 249 | |
| 250 | /** |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 251 | * Interrupt management |
| 252 | */ |
| 253 | protected: |
| 254 | void devIntrPost(uint32_t interrupts); |
| 255 | void devIntrClear(uint32_t interrupts = Regs::Intr_All); |
| 256 | void devIntrChangeMask(uint32_t newmask); |
| 257 | |
| 258 | /** |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 259 | * Memory Interface |
| 260 | */ |
| 261 | public: |
Andreas Hansson | 2ac04c1 | 2015-10-12 04:08:01 -0400 | [diff] [blame] | 262 | Tick read(PacketPtr pkt) override; |
| 263 | Tick write(PacketPtr pkt) override; |
Andreas Hansson | 22c0419 | 2015-10-12 04:07:59 -0400 | [diff] [blame] | 264 | virtual void drainResume() override; |
Nathan Binkert | 2b76b41 | 2005-11-21 21:52:04 -0500 | [diff] [blame] | 265 | |
Andreas Sandberg | 53e777d | 2015-08-07 09:59:13 +0100 | [diff] [blame] | 266 | void prepareIO(ContextID cpu, int index); |
| 267 | void prepareRead(ContextID cpu, int index); |
| 268 | void prepareWrite(ContextID cpu, int index); |
| 269 | // Fault iprRead(Addr daddr, ContextID cpu, uint64_t &result); |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 270 | |
| 271 | /** |
| 272 | * Statistics |
| 273 | */ |
| 274 | private: |
Nathan Binkert | cc95b57 | 2009-03-05 19:09:53 -0800 | [diff] [blame] | 275 | Stats::Scalar totalVnicDistance; |
| 276 | Stats::Scalar numVnicDistance; |
| 277 | Stats::Scalar maxVnicDistance; |
Nathan Binkert | 886c5f8 | 2008-10-09 04:58:23 -0700 | [diff] [blame] | 278 | Stats::Formula avgVnicDistance; |
| 279 | |
| 280 | int _maxVnicDistance; |
| 281 | |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 282 | public: |
Andreas Hansson | 2ac04c1 | 2015-10-12 04:08:01 -0400 | [diff] [blame] | 283 | void regStats() override; |
| 284 | void resetStats() override; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 285 | |
| 286 | /** |
| 287 | * Serialization stuff |
| 288 | */ |
| 289 | public: |
Andreas Hansson | 22c0419 | 2015-10-12 04:07:59 -0400 | [diff] [blame] | 290 | void serialize(CheckpointOut &cp) const override; |
| 291 | void unserialize(CheckpointIn &cp) override; |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 292 | |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 293 | public: |
Ali Saidi | 773cb77 | 2007-08-16 16:49:02 -0400 | [diff] [blame] | 294 | Device(const Params *p); |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 295 | ~Device(); |
| 296 | }; |
| 297 | |
| 298 | /* |
| 299 | * Ethernet Interface for an Ethernet Device |
| 300 | */ |
| 301 | class Interface : public EtherInt |
| 302 | { |
| 303 | private: |
| 304 | Device *dev; |
| 305 | |
| 306 | public: |
| 307 | Interface(const std::string &name, Device *d) |
Ali Saidi | 773cb77 | 2007-08-16 16:49:02 -0400 | [diff] [blame] | 308 | : EtherInt(name), dev(d) |
| 309 | { } |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 310 | |
Ali Saidi | 8f8d095 | 2006-04-24 19:31:50 -0400 | [diff] [blame] | 311 | virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 312 | virtual void sendDone() { dev->transferDone(); } |
| 313 | }; |
| 314 | |
Steve Reinhardt | c69d48f | 2011-01-03 14:35:43 -0800 | [diff] [blame] | 315 | } // namespace Sinic |
Nathan Binkert | 7e4229f | 2004-11-13 17:10:48 -0500 | [diff] [blame] | 316 | |
Andreas Sandberg | 23c961a | 2015-12-10 10:35:18 +0000 | [diff] [blame] | 317 | #endif // __DEV_NET_SINIC_HH__ |