diff options
-rw-r--r-- | SConscript | 1 | ||||
-rw-r--r-- | dev/ns_gige.cc | 66 | ||||
-rw-r--r-- | dev/ns_gige.hh | 11 | ||||
-rw-r--r-- | dev/pktfifo.cc | 68 | ||||
-rw-r--r-- | dev/pktfifo.hh | 95 |
5 files changed, 181 insertions, 60 deletions
diff --git a/SConscript b/SConscript index a2b1c44fa..4fedf25ba 100644 --- a/SConscript +++ b/SConscript @@ -271,6 +271,7 @@ full_system_sources = Split(''' dev/etherdev.cc dev/pciconfigall.cc dev/pcidev.cc + dev/pktfifo.cc dev/scsi.cc dev/scsi_ctrl.cc dev/scsi_disk.cc diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 39bae07ab..e34420a8e 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -1060,7 +1060,6 @@ NSGigE::txReset() DPRINTF(Ethernet, "transmit reset\n"); CTDD = false; - txFifoAvail = maxTxFifoSize; txEnable = false;; txFragPtr = 0; assert(txDescCnt == 0); @@ -1076,7 +1075,6 @@ NSGigE::rxReset() CRDD = false; assert(rxPktBytes == 0); - rxFifoCnt = 0; rxEnable = false; rxFragPtr = 0; assert(rxDescCnt == 0); @@ -1346,9 +1344,7 @@ NSGigE::rxKick() // Must clear the value before popping to decrement the // reference count - rxFifo.front() = NULL; - rxFifo.pop_front(); - rxFifoCnt -= rxPacket->length; + rxFifo.pop(); } @@ -1536,7 +1532,7 @@ NSGigE::transmit() } DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n", - maxTxFifoSize - txFifoAvail); + txFifo.size()); if (interface->sendPacket(txFifo.front())) { #if TRACING_ON if (DTRACE(Ethernet)) { @@ -1556,12 +1552,9 @@ NSGigE::transmit() txBytes += txFifo.front()->length; txPackets++; - txFifoAvail += txFifo.front()->length; - DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n", - txFifoAvail); - txFifo.front() = NULL; - txFifo.pop_front(); + txFifo.avail()); + txFifo.pop(); /* * normally do a writeback of the descriptor here, and ONLY @@ -1829,7 +1822,7 @@ NSGigE::txKick() // this is just because the receive can't handle a // packet bigger want to make sure assert(txPacket->length <= 1514); - txFifo.push_back(txPacket); + txFifo.push(txPacket); /* * this following section is not tqo spec, but @@ -1875,7 +1868,7 @@ NSGigE::txKick() } } else { DPRINTF(EthernetSM, "this descriptor isn't done yet\n"); - if (txFifoAvail) { + if (!txFifo.full()) { txState = txFragRead; /* @@ -1884,7 +1877,7 @@ NSGigE::txKick() * is not enough room in the fifo, just whatever room * is left in the fifo */ - txXferLen = min<uint32_t>(txDescCnt, txFifoAvail); + txXferLen = min<uint32_t>(txDescCnt, txFifo.avail()); txDmaAddr = txFragPtr & 0x3fffffff; txDmaData = txPacketBufPtr; @@ -1910,7 +1903,6 @@ NSGigE::txKick() txPacketBufPtr += txXferLen; txFragPtr += txXferLen; txDescCnt -= txXferLen; - txFifoAvail -= txXferLen; txState = txFifoBlock; break; @@ -2025,7 +2017,7 @@ NSGigE::recvPacket(PacketPtr packet) rxPackets++; DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n", - maxRxFifoSize - rxFifoCnt); + rxFifo.avail()); if (!rxEnable) { DPRINTF(Ethernet, "receive disabled...packet dropped\n"); @@ -2040,15 +2032,14 @@ NSGigE::recvPacket(PacketPtr packet) return true; } - if ((rxFifoCnt + packet->length) >= maxRxFifoSize) { + if (rxFifo.avail() < packet->length) { DPRINTF(Ethernet, "packet will not fit in receive buffer...packet dropped\n"); devIntrPost(ISR_RXORN); return false; } - rxFifo.push_back(packet); - rxFifoCnt += packet->length; + rxFifo.push(packet); interface->recvDone(); rxKick(); @@ -2119,19 +2110,8 @@ NSGigE::serialize(ostream &os) /* * Serialize the data Fifos */ - int txNumPkts = txFifo.size(); - SERIALIZE_SCALAR(txNumPkts); - int i = 0; - pktiter_t end = txFifo.end(); - for (pktiter_t p = txFifo.begin(); p != end; ++p) - (*p)->serialize(csprintf("txFifo%d", i++), os); - - int rxNumPkts = rxFifo.size(); - SERIALIZE_SCALAR(rxNumPkts); - i = 0; - end = rxFifo.end(); - for (pktiter_t p = rxFifo.begin(); p != end; ++p) - (*p)->serialize(csprintf("rxFifo%d", i++), os); + rxFifo.serialize("rxFifo", os); + txFifo.serialize("txFifo", os); /* * Serialize the various helper variables @@ -2174,7 +2154,6 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(txState); SERIALIZE_SCALAR(txEnable); SERIALIZE_SCALAR(CTDD); - SERIALIZE_SCALAR(txFifoAvail); SERIALIZE_SCALAR(txFragPtr); SERIALIZE_SCALAR(txDescCnt); int txDmaState = this->txDmaState; @@ -2188,7 +2167,6 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(rxEnable); SERIALIZE_SCALAR(CRDD); SERIALIZE_SCALAR(rxPktBytes); - SERIALIZE_SCALAR(rxFifoCnt); SERIALIZE_SCALAR(rxDescCnt); int rxDmaState = this->rxDmaState; SERIALIZE_SCALAR(rxDmaState); @@ -2270,22 +2248,8 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) /* * unserialize the data fifos */ - int txNumPkts; - UNSERIALIZE_SCALAR(txNumPkts); - int i; - for (i = 0; i < txNumPkts; ++i) { - PacketPtr p = new PacketData; - p->unserialize(csprintf("rxFifo%d", i), cp, section); - txFifo.push_back(p); - } - - int rxNumPkts; - UNSERIALIZE_SCALAR(rxNumPkts); - for (i = 0; i < rxNumPkts; ++i) { - PacketPtr p = new PacketData; - p->unserialize(csprintf("rxFifo%d", i), cp, section); - rxFifo.push_back(p); - } + rxFifo.unserialize("rxFifo", cp, section); + txFifo.unserialize("txFifo", cp, section); /* * unserialize the various helper variables @@ -2336,7 +2300,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) this->txState = (TxState) txState; UNSERIALIZE_SCALAR(txEnable); UNSERIALIZE_SCALAR(CTDD); - UNSERIALIZE_SCALAR(txFifoAvail); UNSERIALIZE_SCALAR(txFragPtr); UNSERIALIZE_SCALAR(txDescCnt); int txDmaState; @@ -2352,7 +2315,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(rxEnable); UNSERIALIZE_SCALAR(CRDD); UNSERIALIZE_SCALAR(rxPktBytes); - UNSERIALIZE_SCALAR(rxFifoCnt); UNSERIALIZE_SCALAR(rxDescCnt); int rxDmaState; UNSERIALIZE_SCALAR(rxDmaState); diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index fc2c88a6c..90711d63f 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -41,6 +41,7 @@ #include "dev/io_device.hh" #include "dev/ns_gige_reg.h" #include "dev/pcidev.hh" +#include "dev/pktfifo.hh" #include "mem/bus/bus.hh" #include "sim/eventq.hh" @@ -158,10 +159,8 @@ class NSGigE : public PciDev /*** BASIC STRUCTURES FOR TX/RX ***/ /* Data FIFOs */ - pktbuf_t txFifo; - uint32_t maxTxFifoSize; - pktbuf_t rxFifo; - uint32_t maxRxFifoSize; + PacketFifo txFifo; + PacketFifo rxFifo; /** various helper vars */ PacketPtr txPacket; @@ -183,8 +182,6 @@ class NSGigE : public PciDev /** Current Transmit Descriptor Done */ bool CTDD; - /** current amt of free space in txDataFifo in bytes */ - uint32_t txFifoAvail; /** halt the tx state machine after next packet */ bool txHalt; /** ptr to the next byte in the current fragment */ @@ -201,8 +198,6 @@ class NSGigE : public PciDev bool CRDD; /** num of bytes in the current packet being drained from rxDataFifo */ uint32_t rxPktBytes; - /** number of bytes in the rxFifo */ - uint32_t rxFifoCnt; /** halt the rx state machine after current packet */ bool rxHalt; /** ptr to the next byte in current fragment */ diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc new file mode 100644 index 000000000..cf09ae910 --- /dev/null +++ b/dev/pktfifo.cc @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2002-2004 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "base/misc.hh" +#include "dev/pktfifo.hh" + +using namespace std; + +void +PacketFifo::serialize(const string &base, ostream &os) +{ + paramOut(os, base + ".size", _size); + paramOut(os, base + ".maxsize", _maxsize); + paramOut(os, base + ".packets", fifo.size()); + + int i = 0; + std::list<PacketPtr>::iterator p = fifo.begin(); + std::list<PacketPtr>::iterator end = fifo.end(); + while (p != end) { + (*p)->serialize(csprintf("%s.packet%d", base, i), os); + ++p; + ++i; + } +} + +void +PacketFifo::unserialize(const string &base, Checkpoint *cp, + const string §ion) +{ + paramIn(cp, section, base + ".size", _size); + paramIn(cp, section, base + ".maxsize", _maxsize); + int fifosize; + paramIn(cp, section, base + ".packets", fifosize); + + fifo.clear(); + fifo.resize(fifosize); + + for (int i = 0; i < fifosize; ++i) { + PacketPtr p = new PacketData; + p->unserialize(csprintf("%s.packet%d", base, i), cp, section); + fifo.push_back(p); + } +} diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh new file mode 100644 index 000000000..a54a49996 --- /dev/null +++ b/dev/pktfifo.hh @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2002-2004 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DEV_PKTFIFO_HH__ +#define __DEV_PKTFIFO_HH__ + +#include <iosfwd> +#include <list> +#include <string> + +#include "dev/etherpkt.hh" +#include "sim/serialize.hh" + +class Checkpoint; +class PacketFifo +{ + protected: + std::list<PacketPtr> fifo; + int _maxsize; + int _size; + + public: + explicit PacketFifo(int max) : _maxsize(max), _size(0) {} + virtual ~PacketFifo() {} + + int maxsize() const { return _maxsize; } + int packets() const { return fifo.size(); } + int size() const { return _size; } + int avail() const { return _maxsize - _size; } + bool empty() const { return _size == 0; } + bool full() const { return _size >= _maxsize; } + + bool push(PacketPtr ptr) + { + if (avail() < ptr->length) + return false; + + _size += ptr->length; + fifo.push_back(ptr); + return true; + } + + PacketPtr front() { return fifo.front(); } + + void pop() + { + if (empty()) + return; + + _size -= fifo.front()->length; + fifo.front() = NULL; + fifo.pop_front(); + } + + void clear() + { + fifo.clear(); + _size = 0; + } + +/** + * Serialization stuff + */ + public: + void serialize(const std::string &base, std::ostream &os); + void unserialize(const std::string &base, + Checkpoint *cp, const std::string §ion); +}; + +#endif // __DEV_PKTFIFO_HH__ |