Use the new PacketFifo class to avoid manual calculations

--HG--
extra : convert_revision : afa193904b7ed4d5e5c50e9dcb78e8e855b00ecc
This commit is contained in:
Nathan Binkert 2004-11-13 16:52:08 -05:00
parent 8922d69953
commit 4760ae46c6
5 changed files with 181 additions and 60 deletions

View file

@ -271,6 +271,7 @@ full_system_sources = Split('''
dev/etherdev.cc dev/etherdev.cc
dev/pciconfigall.cc dev/pciconfigall.cc
dev/pcidev.cc dev/pcidev.cc
dev/pktfifo.cc
dev/scsi.cc dev/scsi.cc
dev/scsi_ctrl.cc dev/scsi_ctrl.cc
dev/scsi_disk.cc dev/scsi_disk.cc

View file

@ -1060,7 +1060,6 @@ NSGigE::txReset()
DPRINTF(Ethernet, "transmit reset\n"); DPRINTF(Ethernet, "transmit reset\n");
CTDD = false; CTDD = false;
txFifoAvail = maxTxFifoSize;
txEnable = false;; txEnable = false;;
txFragPtr = 0; txFragPtr = 0;
assert(txDescCnt == 0); assert(txDescCnt == 0);
@ -1076,7 +1075,6 @@ NSGigE::rxReset()
CRDD = false; CRDD = false;
assert(rxPktBytes == 0); assert(rxPktBytes == 0);
rxFifoCnt = 0;
rxEnable = false; rxEnable = false;
rxFragPtr = 0; rxFragPtr = 0;
assert(rxDescCnt == 0); assert(rxDescCnt == 0);
@ -1346,9 +1344,7 @@ NSGigE::rxKick()
// Must clear the value before popping to decrement the // Must clear the value before popping to decrement the
// reference count // reference count
rxFifo.front() = NULL; rxFifo.pop();
rxFifo.pop_front();
rxFifoCnt -= rxPacket->length;
} }
@ -1536,7 +1532,7 @@ NSGigE::transmit()
} }
DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n", DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n",
maxTxFifoSize - txFifoAvail); txFifo.size());
if (interface->sendPacket(txFifo.front())) { if (interface->sendPacket(txFifo.front())) {
#if TRACING_ON #if TRACING_ON
if (DTRACE(Ethernet)) { if (DTRACE(Ethernet)) {
@ -1556,12 +1552,9 @@ NSGigE::transmit()
txBytes += txFifo.front()->length; txBytes += txFifo.front()->length;
txPackets++; txPackets++;
txFifoAvail += txFifo.front()->length;
DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n", DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n",
txFifoAvail); txFifo.avail());
txFifo.front() = NULL; txFifo.pop();
txFifo.pop_front();
/* /*
* normally do a writeback of the descriptor here, and ONLY * 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 // this is just because the receive can't handle a
// packet bigger want to make sure // packet bigger want to make sure
assert(txPacket->length <= 1514); assert(txPacket->length <= 1514);
txFifo.push_back(txPacket); txFifo.push(txPacket);
/* /*
* this following section is not tqo spec, but * this following section is not tqo spec, but
@ -1875,7 +1868,7 @@ NSGigE::txKick()
} }
} else { } else {
DPRINTF(EthernetSM, "this descriptor isn't done yet\n"); DPRINTF(EthernetSM, "this descriptor isn't done yet\n");
if (txFifoAvail) { if (!txFifo.full()) {
txState = txFragRead; txState = txFragRead;
/* /*
@ -1884,7 +1877,7 @@ NSGigE::txKick()
* is not enough room in the fifo, just whatever room * is not enough room in the fifo, just whatever room
* is left in the fifo * is left in the fifo
*/ */
txXferLen = min<uint32_t>(txDescCnt, txFifoAvail); txXferLen = min<uint32_t>(txDescCnt, txFifo.avail());
txDmaAddr = txFragPtr & 0x3fffffff; txDmaAddr = txFragPtr & 0x3fffffff;
txDmaData = txPacketBufPtr; txDmaData = txPacketBufPtr;
@ -1910,7 +1903,6 @@ NSGigE::txKick()
txPacketBufPtr += txXferLen; txPacketBufPtr += txXferLen;
txFragPtr += txXferLen; txFragPtr += txXferLen;
txDescCnt -= txXferLen; txDescCnt -= txXferLen;
txFifoAvail -= txXferLen;
txState = txFifoBlock; txState = txFifoBlock;
break; break;
@ -2025,7 +2017,7 @@ NSGigE::recvPacket(PacketPtr packet)
rxPackets++; rxPackets++;
DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n", DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n",
maxRxFifoSize - rxFifoCnt); rxFifo.avail());
if (!rxEnable) { if (!rxEnable) {
DPRINTF(Ethernet, "receive disabled...packet dropped\n"); DPRINTF(Ethernet, "receive disabled...packet dropped\n");
@ -2040,15 +2032,14 @@ NSGigE::recvPacket(PacketPtr packet)
return true; return true;
} }
if ((rxFifoCnt + packet->length) >= maxRxFifoSize) { if (rxFifo.avail() < packet->length) {
DPRINTF(Ethernet, DPRINTF(Ethernet,
"packet will not fit in receive buffer...packet dropped\n"); "packet will not fit in receive buffer...packet dropped\n");
devIntrPost(ISR_RXORN); devIntrPost(ISR_RXORN);
return false; return false;
} }
rxFifo.push_back(packet); rxFifo.push(packet);
rxFifoCnt += packet->length;
interface->recvDone(); interface->recvDone();
rxKick(); rxKick();
@ -2119,19 +2110,8 @@ NSGigE::serialize(ostream &os)
/* /*
* Serialize the data Fifos * Serialize the data Fifos
*/ */
int txNumPkts = txFifo.size(); rxFifo.serialize("rxFifo", os);
SERIALIZE_SCALAR(txNumPkts); txFifo.serialize("txFifo", os);
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);
/* /*
* Serialize the various helper variables * Serialize the various helper variables
@ -2174,7 +2154,6 @@ NSGigE::serialize(ostream &os)
SERIALIZE_SCALAR(txState); SERIALIZE_SCALAR(txState);
SERIALIZE_SCALAR(txEnable); SERIALIZE_SCALAR(txEnable);
SERIALIZE_SCALAR(CTDD); SERIALIZE_SCALAR(CTDD);
SERIALIZE_SCALAR(txFifoAvail);
SERIALIZE_SCALAR(txFragPtr); SERIALIZE_SCALAR(txFragPtr);
SERIALIZE_SCALAR(txDescCnt); SERIALIZE_SCALAR(txDescCnt);
int txDmaState = this->txDmaState; int txDmaState = this->txDmaState;
@ -2188,7 +2167,6 @@ NSGigE::serialize(ostream &os)
SERIALIZE_SCALAR(rxEnable); SERIALIZE_SCALAR(rxEnable);
SERIALIZE_SCALAR(CRDD); SERIALIZE_SCALAR(CRDD);
SERIALIZE_SCALAR(rxPktBytes); SERIALIZE_SCALAR(rxPktBytes);
SERIALIZE_SCALAR(rxFifoCnt);
SERIALIZE_SCALAR(rxDescCnt); SERIALIZE_SCALAR(rxDescCnt);
int rxDmaState = this->rxDmaState; int rxDmaState = this->rxDmaState;
SERIALIZE_SCALAR(rxDmaState); SERIALIZE_SCALAR(rxDmaState);
@ -2270,22 +2248,8 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
/* /*
* unserialize the data fifos * unserialize the data fifos
*/ */
int txNumPkts; rxFifo.unserialize("rxFifo", cp, section);
UNSERIALIZE_SCALAR(txNumPkts); txFifo.unserialize("txFifo", cp, section);
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);
}
/* /*
* unserialize the various helper variables * unserialize the various helper variables
@ -2336,7 +2300,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
this->txState = (TxState) txState; this->txState = (TxState) txState;
UNSERIALIZE_SCALAR(txEnable); UNSERIALIZE_SCALAR(txEnable);
UNSERIALIZE_SCALAR(CTDD); UNSERIALIZE_SCALAR(CTDD);
UNSERIALIZE_SCALAR(txFifoAvail);
UNSERIALIZE_SCALAR(txFragPtr); UNSERIALIZE_SCALAR(txFragPtr);
UNSERIALIZE_SCALAR(txDescCnt); UNSERIALIZE_SCALAR(txDescCnt);
int txDmaState; int txDmaState;
@ -2352,7 +2315,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(rxEnable); UNSERIALIZE_SCALAR(rxEnable);
UNSERIALIZE_SCALAR(CRDD); UNSERIALIZE_SCALAR(CRDD);
UNSERIALIZE_SCALAR(rxPktBytes); UNSERIALIZE_SCALAR(rxPktBytes);
UNSERIALIZE_SCALAR(rxFifoCnt);
UNSERIALIZE_SCALAR(rxDescCnt); UNSERIALIZE_SCALAR(rxDescCnt);
int rxDmaState; int rxDmaState;
UNSERIALIZE_SCALAR(rxDmaState); UNSERIALIZE_SCALAR(rxDmaState);

View file

@ -41,6 +41,7 @@
#include "dev/io_device.hh" #include "dev/io_device.hh"
#include "dev/ns_gige_reg.h" #include "dev/ns_gige_reg.h"
#include "dev/pcidev.hh" #include "dev/pcidev.hh"
#include "dev/pktfifo.hh"
#include "mem/bus/bus.hh" #include "mem/bus/bus.hh"
#include "sim/eventq.hh" #include "sim/eventq.hh"
@ -158,10 +159,8 @@ class NSGigE : public PciDev
/*** BASIC STRUCTURES FOR TX/RX ***/ /*** BASIC STRUCTURES FOR TX/RX ***/
/* Data FIFOs */ /* Data FIFOs */
pktbuf_t txFifo; PacketFifo txFifo;
uint32_t maxTxFifoSize; PacketFifo rxFifo;
pktbuf_t rxFifo;
uint32_t maxRxFifoSize;
/** various helper vars */ /** various helper vars */
PacketPtr txPacket; PacketPtr txPacket;
@ -183,8 +182,6 @@ class NSGigE : public PciDev
/** Current Transmit Descriptor Done */ /** Current Transmit Descriptor Done */
bool CTDD; bool CTDD;
/** current amt of free space in txDataFifo in bytes */
uint32_t txFifoAvail;
/** halt the tx state machine after next packet */ /** halt the tx state machine after next packet */
bool txHalt; bool txHalt;
/** ptr to the next byte in the current fragment */ /** ptr to the next byte in the current fragment */
@ -201,8 +198,6 @@ class NSGigE : public PciDev
bool CRDD; bool CRDD;
/** num of bytes in the current packet being drained from rxDataFifo */ /** num of bytes in the current packet being drained from rxDataFifo */
uint32_t rxPktBytes; uint32_t rxPktBytes;
/** number of bytes in the rxFifo */
uint32_t rxFifoCnt;
/** halt the rx state machine after current packet */ /** halt the rx state machine after current packet */
bool rxHalt; bool rxHalt;
/** ptr to the next byte in current fragment */ /** ptr to the next byte in current fragment */

68
dev/pktfifo.cc Normal file
View file

@ -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 &section)
{
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);
}
}

95
dev/pktfifo.hh Normal file
View file

@ -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 &section);
};
#endif // __DEV_PKTFIFO_HH__